Skip to content
Introducing AI Conversations: Natural Language Interaction for Your Apps! Learn More

CarouselGallery

A Netflix-style horizontal carousel that snaps the focused item to center, scales adjacent items down, and reveals a configurable peek of the next and previous items. Native handlers provide smooth, performant scrolling on each platform.

  • NuGet downloads for Shiny.Maui.Controls
  • NuGet downloads for Shiny.Blazor.Controls
Frameworks
.NET MAUI
Blazor
  • Snap-to-Center — Items snap to the center of the viewport on scroll end, ensuring the focused item is always fully visible. Control snapping behavior via SnapCount.
  • Free Scroll — Set SnapCount="0" for Netflix-style free scrolling with no snap behavior. Items decelerate naturally without locking to a position.
  • Scale Transforms — The focused item renders at FocusedItemScale while all other items render at UnfocusedItemScale, providing a clear visual hierarchy.
  • Peek InsetsPeekAreaInsets (MAUI) or PeekAmount (Blazor) reveals the edges of adjacent items, communicating that the list is scrollable.
  • Infinite Looping — Set IsInfinite="true" to loop the item list continuously.
  • Position TrackingCurrentPosition is a two-way bindable property that reflects and controls the active index.
  • Native Handlers — Android: RecyclerView with snap helper; iOS: UICollectionView with centered flow layout; Windows: ItemsRepeater with scroll snap; Blazor: CSS scroll-snap-type.
claude plugin marketplace add shinyorg/skills
claude plugin install shiny-client@shiny
BLE, GPS, Jobs, Notifications, Push, HTTP Transfers, OBD, Music, Health, DataSync — iOS, Android, Windows, MacOS, Linux, Web
claude plugin install shiny-maui@shiny
Shell, Contact Store
claude plugin install controls@shiny
TableView, BottomSheet, PillView, ImageViewer, Scheduler, Markdown, Mermaid Diagrams — MAUI and Blazor
claude plugin install shiny-mediator@shiny
Mediator/CQRS with middleware and source generators
claude plugin install shiny-data@shiny
DocumentDB and Spatial data libraries
claude plugin install shiny-aspire@shiny
Orleans and Gluetun Aspire integrations
claude plugin install shiny-extensions@shiny
DI, Stores, Reflector, Localization, Hosting modules
copilot plugin marketplace add https://github.com/shinyorg/skills
copilot plugin install shiny-client@shiny
BLE, GPS, Jobs, Notifications, Push, HTTP Transfers, OBD, Music, Health, DataSync — iOS, Android, Windows, MacOS, Linux, Web
copilot plugin install shiny-maui@shiny
Shell, Contact Store
copilot plugin install controls@shiny
TableView, BottomSheet, PillView, ImageViewer, Scheduler, Markdown, Mermaid Diagrams — MAUI and Blazor
copilot plugin install shiny-mediator@shiny
Mediator/CQRS with middleware and source generators
copilot plugin install shiny-data@shiny
DocumentDB and Spatial data libraries
copilot plugin install shiny-aspire@shiny
Orleans and Gluetun Aspire integrations
copilot plugin install shiny-extensions@shiny
DI, Stores, Reflector, Localization, Hosting modules
View Skills Repository
<shiny:CarouselGallery ItemsSource="{Binding Movies}"
CurrentPosition="{Binding SelectedIndex, Mode=TwoWay}"
ItemWidth="280"
ItemHeight="180"
FocusedItemScale="1.0"
UnfocusedItemScale="0.8"
PeekAreaInsets="40"
ItemSpacing="12"
ItemSelectedCommand="{Binding SelectMovieCommand}">
<shiny:CarouselGallery.ItemTemplate>
<DataTemplate>
<Border StrokeShape="{RoundRectangle CornerRadius=12}">
<Image Source="{Binding Thumbnail}" Aspect="AspectFill" />
</Border>
</DataTemplate>
</shiny:CarouselGallery.ItemTemplate>
</shiny:CarouselGallery>
<CarouselGallery Items="movies"
@bind-CurrentPosition="selectedIndex"
ItemWidth="300"
ItemHeight="200"
FocusedItemScale="1.0"
UnfocusedItemScale="0.85"
PeekAmount="40"
ItemSpacing="16"
ShowIndicators="true"
ItemSelected="OnMovieSelected">
<ItemTemplate Context="movie">
<div class="card">
<img src="@movie.Thumbnail" alt="@movie.Title" />
</div>
</ItemTemplate>
</CarouselGallery>
@code {
List<Movie> movies = [];
int selectedIndex = 0;
void OnMovieSelected(Movie movie) { }
}
PropertyMAUI TypeBlazor TypeDefaultDescription
ItemsSource / ItemsIEnumerableIReadOnlyList<TItem>Collection of items to display
ItemTemplateDataTemplateRenderFragment<TItem>Template for each carousel item
ItemWidthdoubledouble— / 300Width of each item in px
ItemHeightdoubledouble— / 200Height of each item in px
ItemSpacingdoubledouble— / 16Spacing between items in px
FocusedItemScaledoubledouble1.0Scale applied to the centered/focused item
UnfocusedItemScaledoubledouble0.8 / 0.85Scale applied to non-focused items
PeekAreaInsets / PeekAmountThicknessdouble— / 40Inset that reveals edges of adjacent items
CurrentPositionintint0Index of the currently focused item (TwoWay)
IsInfiniteboolfalseLoop items infinitely (MAUI only)
SnapCountintint1Number of items to snap into view. Set to 0 for free-scroll (Netflix-style) with no snapping
ShowIndicatorsbooltrueShow dot position indicators (Blazor only)

MAUI:

  • PositionChangedCommand (ICommand) — Fired when CurrentPosition changes; parameter is the new index
  • ItemSelectedCommand (ICommand) — Fired when the user taps a focused item; parameter is the selected item

Blazor:

  • ItemSelected (EventCallback<TItem>) — Fired when the user clicks/taps an item
  • Scrolling past the last item when IsInfinite is false stops at the boundary
  • PeekAreaInsets / PeekAmount clip the outer items to hint at scrollability without requiring a full item to be visible
  • Changing CurrentPosition programmatically animates the carousel to the target item
  • Scale transforms animate smoothly during scroll so intermediate positions show a continuous scale blend
  • When SnapCount is 0, items scroll freely without snapping; CurrentPosition still tracks the closest-to-center item