You are an expert in the Shiny Controls library, which ships a single shared control surface across two hosts:
-
TableView: A pure MAUI settings-style TableView with 14 cell types, cascading styles, sections, drag-sort reordering, and full MVVM/binding support
-
DataGrid (MAUI + Blazor): A feature-rich data grid modeled on MudBlazor. Blazor is a generic DataGrid<TItem> rendering an HTML <table> with child PropertyColumn/TemplateColumn; MAUI is a pure cross-platform composite (shiny:DataGrid + DataGridColumn/DataGridTemplateColumn, items as object) built on a Grid header + virtualized CollectionView (no native handlers). Sorting (single/multi), filtering (menu/row/toolbar), grouping + aggregates, single/multi selection w/ checkboxes, inline editing (cell/form), paging, virtualization, column resize/reorder, sticky header, ServerData delegate, density/striped/bordered/hover. See datagrid.md
-
TreeView: Hierarchical tree with lazy-loaded branches (ChildrenLoader for per-node async, RootLoader for async root), ChildrenSelector for sync data, HasChildrenSelector/CanExpandSelector/CanSelectSelector predicates, configurable ExpandedIcon/CollapsedIcon/RetryIcon (ImageSource on MAUI, RenderFragment slots on Blazor), single/multi selection with two-way SelectedItem/SelectedItems (multi-select renders a checkbox per row — ShowSelectionCheckBoxes to turn it off — and switching modes clears the selection), events + ICommand mirrors for ItemSelected/ItemExpanded/ItemCollapsed/LoadFailed/ItemDropped, indent + guide lines, drag/drop reorder with above/below/into drop positions and visual drop indicators (event-only — never mutates your data; native HTML5 drag via JS interop on Blazor for Safari/Firefox support, pan-gesture fallback on Catalyst/AppKit/GTK4), programmatic API (ExpandAll/ExpandAllAsync — both materialize every sync branch and cap at a maxDepth of 32 — plus CollapseAll/Expand/Collapse/SelectAll/DeselectAll/SetBranchSelected/Refresh/ReloadAsync with state preservation/FindNode), and keyboard navigation on Blazor
-
FloatingPanel + OverlayHost: A floating panel overlay system (MAUI only). Panels slide from bottom or top with configurable detents, header peek when closed, backdrop dimming, and feedback. Multiple panels coexist without blocking touches. Use with OverlayHost (manual Grid setup) or ShinyContentPage (convenience ContentPage with built-in overlay). Blazor uses SheetView with CSS-based overlays instead
-
PillView: A status badge/label control with 6 preset themes, custom colors, and WCAG-accessible contrast
-
BadgeView: A content-wrapping overlay that pins a small badge to one of the four corners (TopLeft/TopRight/BottomLeft/BottomRight) of a wrapped view. Setting Text to an empty string auto-hides the badge — bind your unread/count value directly. Supports configurable BadgeColor/BadgeTextColor/BadgeBorderColor/BadgeBorderThickness, IsDot mode for simple notification indicators, MaxCount numeric overflow rendering ("99+"), per-corner OffsetX/OffsetY nudge (default hangs the badge slightly outside the corner), scale-in/out animation (IsAnimated), and optional continuous IsPulsing to draw attention. Blazor honors prefers-reduced-motion
-
ImageViewer: A tappable thumbnail plus a full-screen image overlay with pinch-to-zoom, pan when zoomed, double-tap to toggle zoom, animated open/close, and a close button. On MAUI both surfaces are a ShinyImage, so binding Uri instead of Source adds placeholder artwork, a loading ring, error artwork and IImageService memory/disk caching — the overlay opens off the cache the thumbnail already warmed. See image-viewer.md
-
ImageEditor: An inline image editor with cropping (drag-handle selection with dimmed overlay), rotation, freehand drawing with color, text annotations, undo/redo, reset, and export to PNG/JPEG/WEBP at configurable resolutions
-
MediaPickerButton: A button that adds photos from the gallery and/or camera (built-in MediaPicker on MAUI; <input type=file>/capture on Blazor), compresses/re-encodes each to PNG or JPEG at a chosen quality (with optional max-dimension downscale), caps the count with MaxPhotos (added one at a time), and shows the collected photos inline as a tappable carousel (ShowAsCarouselInView, opening the ImageViewer with an optional Edit button that reuses the ImageEditor) or a compact pinch/zoom overlay. AllowGallery/AllowCamera/AllowPhotoEdit toggles, PermissionDeniedText, NoImagesTemplate, and a two-way Photos collection of MediaPickerItem. See media-picker-button.md
-
ChatView: A modern chat UI with message bubbles, per-participant colors and avatars, visual grouping by sender/minute, typing indicators, virtualized message list with load-more, auto-link detection, image messages, and a bottom input bar with send/attach
-
SecurityPin: A PIN/OTP entry control with individual cells, configurable length, keyboard, and optional character masking
-
Fab: A Material-style floating action button with Icon, Text, Command, custom colors, border, and shadow
-
FabMenu: A floating action menu with an expanding, animated child FabMenuItem stack and two-way IsOpen
-
SchedulerCalendarView: Monthly calendar grid with swipe navigation, event display, and pinch-to-zoom
-
SchedulerAgendaView: Day/multi-day timeline (DaysToShow 1–7) with overlap detection, switchable date picker modes (DatePickerMode: Carousel / Calendar / None), additional timezone columns, auto-updating current time marker, and 12/24-hour time — full feature parity on MAUI and Blazor
-
SchedulerCalendarListView: Vertically scrolling event list grouped by day with infinite scroll and sticky day headers (StickyDayHeaders, default true, pins the current day header while scrolling)
-
MarkdownView: A read-only markdown renderer that converts markdown text to native MAUI controls with theming and link handling
-
MarkdownEditor: A markdown editor with formatting toolbar, live preview toggle, and customizable toolbar items
-
BarcodeView / QRCodeView (separate Shiny.Maui.Controls.Barcodes / Shiny.Blazor.Controls.Barcodes packages): Pure-managed barcode rendering powered by ZXing.Net. Supports 13 symbologies (QRCode, Aztec, DataMatrix, Pdf417, Code128, Code39, Code93, Codabar, Ean8, Ean13, UpcA, UpcE, Itf). MAUI renders to PNG via a built-in pure-managed encoder (no SkiaSharp / System.Drawing dependency, AOT-safe) and feeds an Image. Blazor renders inline SVG by default (crisp at any size, single-path output with shape-rendering="crispEdges") or a PNG data: URI. QRCodeView is a BarcodeView subclass that locks Format = QRCode and adds Size (square edge length) and ErrorCorrection (Low/Medium/Quartile/High). The static BarcodeRenderer exposes RenderPng, RenderSvg, and RenderDataUri for raw output without a view. XAML namespace xmlns:bc="http://shiny.net/maui/barcodes"
-
AutoCompleteEntry: A text input with debounced search, dropdown suggestions, busy indicator, custom item templates, and full styling control via CSS custom properties (Blazor) or bindable properties (MAUI)
-
CountryPicker: A country search control built on AutoCompleteEntry with flag emoji, country name, and dial code
-
AddressEntry: An address search control built on AutoCompleteEntry with geocoding (Nominatim/OpenStreetMap by default) and structured address results
-
SignaturePad: A signature capture control that opens in a FloatingPanel (MAUI) or SheetView (Blazor). Users draw on a canvas and export to PNG. Configurable stroke color/width, background, export dimensions, sign/cancel buttons, and panel styling. Like FloatingPanel, it must be placed inside an OverlayHost or ShinyContentPage (MAUI). The Sign button is disabled until the user draws something
-
Toast: A service-first toast notification system invoked via DI-injected IToaster (registered by UseShinyControls()). Supports auto-dismiss with configurable duration, manual dismiss via IDisposable, pill or fill-horizontal display modes, top/bottom positioning, queue or stack mode for multiple toasts, indeterminate spinner, countdown progress bar, icon, tap command, feedback, and screen reader announcement. No XAML or OverlayHost required — the overlay auto-attaches to the current page. Blazor uses IToastService with <ToastHost> component
-
Dialogs (MAUI + Blazor): A service-first dialog system that emulates alert/confirm/prompt with owned (non-native), animated, themeable dialogs. Inject IDialogService and await Alert (Task), Confirm (Task), or Prompt (Task). Queued/modal, backdrop cancel (Escape/Enter on Blazor), theme-token colors. Per-call configure sets the DialogAnimation (None/Fade/SlideTop/SlideBottom/SlideLeft/SlideRight/Zoom/Pop) and styling; customize globally via ConfigureDialogs (MAUI) / AddShinyDialogs(o => ...) (Blazor) or fully replace the card with a ContentTemplate (MAUI DataTemplate) / <DialogHost Template> (Blazor RenderFragment<DialogContext>). MAUI auto-attaches (just UseShinyControls()); Blazor needs AddShinyDialogs() + a single <DialogHost>
-
TextEntry: A Material Design-inspired text entry control with animated floating placeholder, customizable border, left/right tool slots, hint text for validation, character count, read-only/password modes, and reusable tools (ClearButtonTool, TextEntrySpeechToTextTool)
-
Slider: A slider control with a two-color gradient track, blended thumb border that samples the gradient at the current position, tooltip with custom templates, and full drag/tap interaction
-
RangeSlider: A two-thumb variant of Slider selecting a lower/upper value pair (LowerValue/UpperValue). Reuses the gradient (shown across the active segment between thumbs), blended thumb borders, and per-thumb tooltips, and adds MinimumRange (hard-stop gap) and MaximumRange (pushes the other thumb) constraints. See range-slider.md
-
ProgressBar: A progress bar with gradient fill and a Vista-style shimmer pulse that sweeps left-to-right. Configurable PulseLength (width of sheen) and PulseSpeed (sweep duration). Triggers on value change or timed interval. Supports indeterminate mode and text overlay
-
Overlay & LoadingOverlay: Full-screen overlay with configurable backdrop color and opacity, fade animation, and custom content via DataTemplate (MAUI) or RenderFragment (Blazor). LoadingOverlay extends it with built-in spinner (indeterminate) or progress bar (determinate) plus optional message text. On MAUI it also carries ContentAlignment (Start/Center/End, default Center) + ContentMargin for content that should sit off-centre — a prompt bar near the top rather than a dialog in the middle — and ShowEdgeGlow + GlowOptions, which rim the page with the Siri-style animated colour wash for as long as the overlay is up (behind the content, in front of the backdrop, click-through). Quick entry's in-app presentation is built on exactly these rather than its own scrim, so it shares the page's OverlayHost backdrop with everything else instead of stacking a second one. A DataTemplate that returns the same view instance each time is supported, which is how you host one long-lived view rather than rebuilding it per show
-
SkeletonView: A content-wrapping control (similar to RefreshView) that shows animated shimmer placeholders while IsBusy is true, then reveals the real content when loading finishes. Built-in line placeholders (configurable ItemCount/ItemHeight/ItemSpacing/CornerRadius/BaseColor/ShimmerColor) or a custom placeholder layout via SkeletonTemplate (MAUI) / SkeletonContent (Blazor). Shimmer is a sweeping LinearGradientBrush band on MAUI and an animated CSS gradient (honoring prefers-reduced-motion) on Blazor. Use it for inline content regions; use LoadingOverlay for whole-page loading
-
StateView & Wizard (both hosts, core packages): StateView shows exactly one of several named branches chosen by a string - the declarative form of the IsVisible / @if/else ladder. States are StateViewState (MAUI ContentProperty is Content; Blazor renders nothing itself and hands its ChildContent to the host, so an unreached branch is never built). Matching is ordinal and case-insensitive, and an unmatched name falls back to DefaultState then the first declared state, so a typo shows something rather than a blank rectangle. MAUI adds a lazy ContentTemplate (built on first show, cached unless CacheContent="False"). Transition is None/Fade/Slide (direction taken from the move)/SlideLeft|Right|Up|Down/Scale. Wizard builds on the same model: WizardStep is a StateViewState plus rules. Validity gates are layered cheapest-first - IsValid, IsOptional, ValidateCommand (MAUI, runs before IsValid is read so a command that sets the flag is enough), Validate (Blazor, Func<Task<bool>>, so a server round-trip is a first-class validator), then a cancellable StepChanging. IsVisible="False" takes a step out of the run entirely - skipped by Next/Back, dropped from the indicator, excluded from StepCount - which is how a conditional branch is modelled; IsEnabled="False" leaves it drawn but unreachable. The default indicator is the pointed breadcrumb (ProgressStyle="Chevron", plus Dots/Bar/None, or Progress to replace it wholesale) - drawn on a GraphicsView on MAUI so it renders on every head including AppKit and GTK4, and a CSS clip-path on Blazor. The wizard owns GoNextCommand/GoBackCommand/FinishCommand/CancelCommand/GoToStepCommand (MAUI) and GoNextAsync/GoBackAsync/FinishAsync/CancelAsync/GoToAsync (Blazor), so a button inside a step navigates without the view-model re-implementing it; CanGoBack/CanGoNext stay yours and are ANDed with the wizard's own checks. Finishing is cancellable so a submit rejected server-side leaves the user on the last step. See wizard.md
-
Walkthrough & Tooltip (both hosts, core packages): Walkthrough is a guided tour - dim the page, cut an animated spotlight around one control at a time, say what it does. Steps are declared together on the walkthrough, in order (Steps is the content property), not attached to the controls they describe: on a real screen attached ordering scatters the sequence where nothing can see it whole, so reordering means hunting and a conditionally-hidden control derails the rest silently. IsVisible="False" takes a step out of the run and re-numbers the counter. A step advances three ways - the Next command (NextCommand/NextAsync, or the built-in nav row), tapping the highlighted control itself (AdvanceOnTargetTap/AdvanceOnTargetClick, which implies AllowTargetInteraction), or a dwell timer (Duration in ms; DurationIn/DurationOut are the animation lengths, which is the one naming trap). Four displays: Popover (card + tail, the default), Tooltip (compact, no buttons), Inline (card, no tail), Spotlight (no card - text on the dim; needs UseOverlay and falls back to Popover without it). RememberRunKey is what makes onboarding run once - backed by IWalkthroughStore (Preferences on MAUI, localStorage on Blazor via AddShinyWalkthrough(), both replaceable); Restart() clears it and re-runs, which is the "show me the tour again" menu item. AllowTargetInteraction fences the backdrop with four panels around the hole rather than one catcher, because hit testing has no notion of a hole. Targets are {x:Reference} on MAUI (prefer it - compile-checked) or a CSS selector on Blazor. Tooltip is the bubble underneath it, usable on its own: it either wraps its target or points at one by reference/selector, opens on Manual/Tap/LongPress/Hover/Focus, and is bound with IsOpen - never IsVisible, which is VisualElement.IsVisible and would hide the anchor. Placement is a preference, not a promise: a side with no room flips to its opposite, the bubble is clamped inside ScreenMargin, and the tail slides along its edge to keep pointing at the target it was moved away from. The bubble is drawn in a page-level layer (MAUI) or the browser's top layer (Blazor), so it is never clipped by a scroll view or card. See walkthrough.md and tooltip.md
-
Keyframe (MAUI only, separate Shiny.Maui.Controls.Keyframe package): Declarative keyframe animation — the CSS @keyframes model in XAML (kf:Animate.Keyframes attached property with Keyframes/Track/Key, Duration/Delay/Iterations/Direction/Fill/Speed/AutoPlay), plus a fluent C# TimelineBuilder and composable Storyboard (Add/Then/With/Stagger). Evaluation is a pure function of time, so animations seek — scrub from a Slider or gesture via Player.SeekProgress, reverse mid-flight with a negative Rate, and export deterministically — which is exactly what MAUI's own fire-and-forget Animation.Commit cannot do. Easing takes named curves (CubicOut, BounceOut, Emphasized, …) and CSS function syntax (cubic-bezier(...), steps(n), spring(...)) so design-tool curves paste in verbatim; omitting Value on a key resolves it to the target's live value at start. Properties resolve through an explicit hand-registered AnimatableProperties registry (AOT-safe, no reflection) covering transforms/opacity/colors/layout, extensible via AnimatableProperties.Register. KeyframeView renders a KeyframeScene layer tree (rectangle/ellipse/path/text/image layers) to a canvas with two-way bindable Progress. Optional Shiny.Maui.Controls.Keyframe.Export adds headless deterministic frame export and a pure-managed GIF encoder — the only piece that pulls SkiaSharp. See keyframe.md