A rich, ready-to-use UI controls library for both .NET MAUI and Blazor. One package per host covers TableView, Scheduler, BottomSheet, Fab/FabMenu, PillView, SecurityPin, and ImageViewer. Markdown and Mermaid Diagrams ship as separate add-on packages per host.
dotnet add package Shiny.Maui.ControlsRegister in your MauiProgram.cs:
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseShinyControls();Add the XAML namespace:
xmlns:shiny="http://shiny.net/maui/controls"For Markdown controls (separate package):
dotnet add package Shiny.Maui.Controls.Markdownxmlns:md="http://shiny.net/maui/markdown"For Mermaid Diagrams (separate package):
dotnet add package Shiny.Maui.Controls.MermaidDiagramsxmlns:diagram="http://shiny.net/maui/diagrams"dotnet add package Shiny.Blazor.Controls
dotnet add package Shiny.Blazor.Controls.Markdown # optional
dotnet add package Shiny.Blazor.Controls.MermaidDiagrams # optionalAdd the @using directives — typically in _Imports.razor:
@using Shiny.Blazor.Controls
@using Shiny.Blazor.Controls.Cells
@using Shiny.Blazor.Controls.Sections
@using Shiny.Blazor.Controls.Scheduler
@using Shiny.Blazor.Controls.Markdown
@using Shiny.Blazor.Controls.MermaidDiagramsNo DI registration is required — drop the components into any .razor page.
| MAUI (XAML) | Blazor (Razor) |
|---|---|
<shiny:TableView> with <shiny:TableRoot> |
<TableView> (no TableRoot wrapper) |
<shiny:PillView> |
<Pill> |
<shiny:BottomSheetView> with SheetContent property |
<BottomSheetView> with <SheetContent> child |
Value="{Binding Pin}" (TwoWay) |
@bind-Value="pin" |
IsOpen="{Binding IsOpen, Mode=TwoWay}" |
@bind-IsOpen="isOpen" |
Command="{Binding DoCommand}" |
OnClick="DoAsync" / Clicked="DoAsync" |
Color type (e.g. Colors.Blue) |
CSS color string (e.g. "#2196F3") |
Fab.Icon="add.png" (ImageSource) |
<Fab Icon="+"> (inline text/SVG string) |
ItemTemplate as DataTemplate |
ItemTemplate as RenderFragment<object> |
ISchedulerEventProvider is identical across both hosts.
Calendar and agenda views for displaying events and appointments, powered by ISchedulerEventProvider.
| Calendar | Agenda | Event List |
|---|---|---|
![]() |
![]() |
![]() |
SchedulerCalendarView - Month calendar grid with event indicators, swipe navigation, and date selection.
<shiny:SchedulerCalendarView
Provider="{Binding Provider}"
SelectedDate="{Binding SelectedDate}"
DisplayMonth="{Binding DisplayMonth}" />SchedulerAgendaView - Day/multi-day timeline with time slots, overlapping event layout, current time marker, and optional timezone columns.
<shiny:SchedulerAgendaView
Provider="{Binding Provider}"
SelectedDate="{Binding SelectedDate}"
DaysToShow="{Binding DaysToShow}"
ShowAdditionalTimezones="{Binding ShowAdditionalTimezones}" />SchedulerCalendarListView - Scrollable event list grouped by day with infinite scroll loading.
<shiny:SchedulerCalendarListView
Provider="{Binding Provider}"
SelectedDate="{Binding SelectedDate}" />ISchedulerEventProvider - Implement this interface to supply event data:
public class MyEventProvider : ISchedulerEventProvider
{
public Task<IReadOnlyList<SchedulerEvent>> GetEvents(DateTimeOffset start, DateTimeOffset end) { ... }
public void OnEventSelected(SchedulerEvent selectedEvent) { ... }
public bool CanCalendarSelect(DateOnly selectedDate) => true;
public void OnCalendarDateSelected(DateOnly selectedDate) { }
public bool CanSelectAgendaTime(DateTimeOffset selectedTime) => true;
public void OnAgendaTimeSelected(DateTimeOffset selectedTime) { }
}A bottom sheet overlay that slides up from the bottom of the screen with configurable snap positions (detents).
| Closed | Open |
|---|---|
![]() |
![]() |
<shiny:BottomSheetView
IsOpen="{Binding IsSheetOpen}"
HasBackdrop="True"
CloseOnBackdropTap="True"
SheetCornerRadius="16">
<shiny:BottomSheetView.Detents>
<shiny:DetentValue Value="Quarter" />
<shiny:DetentValue Value="Half" />
<shiny:DetentValue Value="Full" />
</shiny:BottomSheetView.Detents>
<shiny:BottomSheetView.SheetContent>
<!-- Your content here -->
</shiny:BottomSheetView.SheetContent>
</shiny:BottomSheetView>| Property | Type | Description |
|---|---|---|
| IsOpen | bool | Show/hide the sheet (TwoWay) |
| Detents | ObservableCollection<DetentValue> | Snap positions (Quarter, Half, Full) |
| SheetContent | View | Content displayed in the sheet |
| HasBackdrop | bool | Fade backdrop behind sheet |
| CloseOnBackdropTap | bool | Close when backdrop tapped |
| SheetCornerRadius | double | Top corner radius |
| HandleColor | Color | Drag handle color |
| SheetBackgroundColor | Color | Sheet background color |
| AnimationDuration | double | Animation speed (ms) |
| ExpandOnInputFocus | bool | Auto-expand when input focused |
A full-screen image overlay with pinch-to-zoom, pan, double-tap zoom, and animated open/close transitions.
| Gallery | Viewer |
|---|---|
![]() |
![]() |
<Grid>
<!-- Page content with tappable images -->
<ScrollView>
<VerticalStackLayout>
<Image Source="photo.png">
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding OpenViewerCommand}"
CommandParameter="photo.png" />
</Image.GestureRecognizers>
</Image>
</VerticalStackLayout>
</ScrollView>
<!-- ImageViewer overlays on top -->
<shiny:ImageViewer Source="{Binding SelectedImage}"
IsOpen="{Binding IsViewerOpen}" />
</Grid>| Property | Type | Description |
|---|---|---|
| Source | ImageSource? | The image to display |
| IsOpen | bool | Show/hide the viewer (TwoWay) |
| MaxZoom | double | Maximum zoom scale (default: 5.0) |
Features:
- Pinch-to-zoom with origin tracking
- Pan when zoomed (clamped to image bounds)
- Double-tap to zoom in (2.5x) / reset
- Animated fade open/close with backdrop
- Close button overlay
Pill/chip/tag elements for displaying categories, filters, or status indicators with predefined or custom color schemes.
<shiny:PillView Text="Success" Type="Success" />
<shiny:PillView Text="Warning" Type="Warning" />
<shiny:PillView Text="Custom" PillColor="Purple" PillTextColor="White" />| Pill Type | Description |
|---|---|
| None | Default/neutral |
| Success | Green |
| Info | Blue |
| Warning | Yellow |
| Caution | Orange |
| Critical | Red |
A Material Design-style floating action button, plus an expanding multi-action menu that animates up from the main FAB.
| Closed | Menu Open |
|---|---|
![]() |
![]() |
<!-- Single Fab -->
<shiny:Fab Icon="add.png"
Text="Add Item"
FabBackgroundColor="#4CAF50"
TextColor="White"
Command="{Binding AddCommand}"
HorizontalOptions="End"
VerticalOptions="End"
Margin="24" />
<!-- FabMenu with child items -->
<shiny:FabMenu IsOpen="{Binding IsMenuOpen}"
Icon="plus.png"
FabBackgroundColor="#2196F3"
HorizontalOptions="End"
VerticalOptions="End"
Margin="24">
<shiny:FabMenuItem Icon="share.png" Text="Share" Command="{Binding ShareCommand}" />
<shiny:FabMenuItem Icon="edit.png" Text="Edit" Command="{Binding EditCommand}" />
<shiny:FabMenuItem Icon="delete.png" Text="Delete" Command="{Binding DeleteCommand}" />
</shiny:FabMenu>Fab properties:
| Property | Type | Default | Description |
|---|---|---|---|
| Icon | ImageSource? | null | Button icon |
| Text | string? | null | Optional label; when null the Fab is a perfect circle |
| Command | ICommand? | null | Invoked when the Fab is tapped |
| CommandParameter | object? | null | Parameter passed to the Command |
| FabBackgroundColor | Color | #2196F3 | Fill color |
| BorderColor | Color? | null | Outline stroke color |
| BorderThickness | double | 0 | Outline stroke thickness |
| TextColor | Color | White | Label color |
| FontSize | double | 14 | Label font size |
| FontAttributes | FontAttributes | None | Label font attributes |
| Size | double | 56 | Height of the Fab (diameter when circular) |
| IconSize | double | 24 | Icon image size |
| HasShadow | bool | true | Show drop shadow |
Events: Clicked.
FabMenu properties (plus all main-Fab pass-throughs above):
| Property | Type | Default | Description |
|---|---|---|---|
| IsOpen | bool | false | Two-way bindable; opens/closes the menu with animation |
| Items | IList<FabMenuItem> |
empty | Menu items (content property — place items directly inside the FabMenu) |
| HasBackdrop | bool | true | Show a dim backdrop while open |
| BackdropColor | Color | Black | Backdrop color |
| BackdropOpacity | double | 0.4 | Backdrop peak opacity |
| CloseOnBackdropTap | bool | true | Close when backdrop is tapped |
| CloseOnItemTap | bool | true | Close after any item is tapped |
| AnimationDuration | uint | 200 | Open/close animation duration (ms) |
Events: ItemTapped — fires the FabMenuItem that was tapped.
Methods: Open(), Close(), Toggle().
FabMenuItem properties:
| Property | Type | Default | Description |
|---|---|---|---|
| Icon | ImageSource? | null | Circular icon |
| Text | string? | null | Side label next to the icon |
| Command | ICommand? | null | Invoked when tapped |
| CommandParameter | object? | null | Parameter for the Command |
| FabBackgroundColor | Color | #2196F3 | Icon button fill |
| BorderColor | Color? | null | Icon button outline |
| BorderThickness | double | 0 | Icon button outline thickness |
| TextColor | Color | Black | Side-label text color |
| LabelBackgroundColor | Color | White | Side-label background |
| FontSize | double | 13 | Side-label font size |
| Size | double | 44 | Icon button diameter |
| IconSize | double | 20 | Icon image size |
Placement tip: FabMenu should live in a Grid that fills the page (the same placement pattern as BottomSheetView / ImageViewer) so the backdrop can cover the page content.
A PIN entry control with individually rendered cells that captures input through a hidden Entry. Digits remain visible by default and can optionally be masked with any character.
<shiny:SecurityPin Length="4"
HideCharacter="*"
Value="{Binding Pin}"
Keyboard="Numeric"
Completed="OnPinCompleted" />| Property | Type | Default | Description |
|---|---|---|---|
| Length | int | 4 | Number of PIN cells |
| Value | string | "" | Current PIN value (TwoWay) |
| Keyboard | Keyboard | Numeric | Keyboard type for input |
| HideCharacter | string? | null | When set, masks entered characters; when null/empty, shows actual values |
| CellSize | double | 50 | Width/height of each cell |
| CellSpacing | double | 8 | Space between cells |
| CellCornerRadius | double | 8 | Border corner radius |
| CellBorderColor | Color? | null | Cell border color |
| CellFocusedBorderColor | Color? | null | Border color for the active cell |
| CellBackgroundColor | Color? | null | Cell fill color |
| CellTextColor | Color? | null | Entered character color |
| FontSize | double | 24 | Character font size |
Events: Completed fires with a SecurityPinCompletedEventArgs once the entered value reaches Length.
Methods: Focus(), Unfocus(), Clear().
A settings-style table view with 14+ built-in cell types, section grouping, drag-to-reorder, and dynamic data binding.
| Basic | Dynamic | Drag & Sort | Pickers | Styling |
|---|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
<shiny:TableView>
<shiny:TableRoot>
<shiny:TableSection Title="General">
<shiny:SwitchCell Title="Wi-Fi" On="{Binding WifiEnabled}" />
<shiny:EntryCell Title="Username" Text="{Binding Username}" />
<shiny:PickerCell Title="Theme" ItemsSource="{Binding Themes}" SelectedItem="{Binding SelectedTheme}" />
</shiny:TableSection>
</shiny:TableRoot>
</shiny:TableView>Cell Types:
| Cell | Description |
|---|---|
| SwitchCell | Toggle switch |
| EntryCell | Text input field |
| CheckboxCell | Checkbox with accent color |
| RadioCell | Radio button with section-level grouping |
| CommandCell | Tappable row with optional arrow indicator |
| ButtonCell | Command-bound button |
| LabelCell | Read-only text display |
| PickerCell | Single or multi-select picker |
| TextPickerCell | String list picker |
| DatePickerCell | Date selection with min/max bounds |
| TimePickerCell | Time selection |
| DurationPickerCell | TimeSpan picker with min/max |
| NumberPickerCell | Integer picker with min/max/unit |
| SimpleCheckCell | Checkmark indicator |
| CustomCell | Custom view content with drag-reorder support |
Dynamic Sections - Bind to a collection to generate sections from data:
<shiny:TableView ItemsSource="{Binding Items}" ItemTemplate="{StaticResource SectionTemplate}" />Separate NuGet packages:
Shiny.Maui.Controls.Markdown/Shiny.Blazor.Controls.Markdown
Render and edit markdown content using native MAUI controls — no WebView required on MAUI. Auto-resolves Light/Dark theming. Available for both MAUI and Blazor.
| Viewer | Editor |
|---|---|
![]() |
![]() |
MarkdownView — Read-only markdown renderer:
<md:MarkdownView Markdown="{Binding DocumentContent}" Padding="16" />| Property | Type | Description |
|---|---|---|
| Markdown | string | Markdown content to render |
| Theme | MarkdownTheme? | Rendering theme (auto Light/Dark if null) |
| IsScrollEnabled | bool | Enable/disable scrolling (default: true) |
Events: LinkTapped — fired when a link is tapped; set Handled = true to prevent default browser launch.
MarkdownEditor — Editor with formatting toolbar and live preview:
<md:MarkdownEditor Markdown="{Binding NoteContent, Mode=TwoWay}"
Placeholder="Start writing..."
Padding="8" />| Property | Type | Description |
|---|---|---|
| Markdown | string | Markdown content (TwoWay) |
| Theme | MarkdownTheme? | Preview theme (auto Light/Dark if null) |
| Placeholder | string | Placeholder text |
| ToolbarItems | IReadOnlyList<MarkdownToolbarItem>? | Toolbar buttons (default set provided) |
| IsPreviewVisible | bool | Toggle preview pane (TwoWay) |
| ToolbarBackgroundColor | Color? | Toolbar background |
| EditorBackgroundColor | Color? | Editor background |
Features:
- Formatting toolbar: bold, italic, headings, lists, code, links, blockquotes
- Live preview toggle
- Auto-growing editor
- Full Markdig support: tables, task lists, strikethrough, fenced code blocks
- Customizable themes with colors, font sizes, and spacing
- Custom toolbar item support
Separate NuGet packages:
Shiny.Maui.Controls.MermaidDiagrams/Shiny.Blazor.Controls.MermaidDiagrams
Native Mermaid flowchart renderer — no WebView, no SkiaSharp, AOT compatible on MAUI. Parses Mermaid syntax and renders interactive diagrams with pan and zoom support. Available for both MAUI and Blazor.
| Flowchart | Editor | Themes | Subgraphs |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
dotnet add package Shiny.Maui.Controls.MermaidDiagramsxmlns:diagram="http://shiny.net/maui/diagrams"<diagram:MermaidDiagramControl
DiagramText="graph TD A[Start] --> B{Decision} B -->|Yes| C[Do Something] B -->|No| D[Do Other] C --> E[End] D --> E"
HorizontalOptions="Fill"
VerticalOptions="Fill" />Features:
- Mermaid
graph/flowchartsyntax (TD, LR, BT, RL directions) - 6 node shapes: Rectangle, RoundedRectangle, Stadium, Circle, Diamond, Hexagon
- 6 edge styles: Solid, Open, Dotted, DottedOpen, Thick, ThickOpen
- Subgraph support with nested grouping
- 4 built-in themes: Default, Dark, Forest, Neutral
- Pan and pinch-to-zoom gestures
- Sugiyama layered graph layout algorithm





















