Blazorise Gestures component
Detect swipes and pointer gesture lifecycle events on wrapped content.
<Gestures> is a wrapper component for touch, pen, and mouse pointer gestures. Use it around content that should react to directional swipes, such as sidebars, galleries, item cards, or custom mobile navigation.
The high-level Swiped, Tapped, and LongPressed events are best for most scenarios. Use GestureStarted, GestureMoved, and GestureEnded when the UI needs to react while the pointer is moving.
Examples
Basic Swipe
Wrap content withGestures and handle Swiped to react to a horizontal swipe.
Waiting for swipe
Swipe left or right inside this area.
<Gestures Direction="GestureDirection.Horizontal" TouchAction="GestureTouchAction.PanY" Swiped=""> <Div Border="Border.Is1.Rounded" Background="Background.Light" Padding="Padding.Is4" Style="user-select: none;"> <Div Flex="Flex.JustifyContent.Between.AlignItems.Center" Gap="Gap.Is3"> <Div> <Heading Size="HeadingSize.Is5" Margin="Margin.Is0.FromBottom"> @Title </Heading> <Paragraph TextColor="TextColor.Secondary" Margin="Margin.Is2.FromTop.Is0.FromBottom"> Swipe left or right inside this area. </Paragraph> </Div> <Badge Color="" Pill>@DirectionText</Badge> </Div> </Div> </Gestures>
@code { private string Title { get; set; } = "Waiting for swipe"; private string DirectionText { get; set; } = "None"; private Color BadgeColor { get; set; } = Color.Secondary; private Task OnSwiped( SwipeEventArgs eventArgs ) { DirectionText = eventArgs.Direction.ToString(); Title = $"Swiped {DirectionText.ToLowerInvariant()}"; BadgeColor = eventArgs.Direction == GestureDirection.Left ? Color.Primary : Color.Info; return Task.CompletedTask; } }
Swipe Gallery
Horizontal swipe gestures are useful for galleries, carousels, onboarding panels, and other item-by-item navigation.Overview
Introduce key content one panel at a time.
<Gestures Direction="GestureDirection.Horizontal" TouchAction="GestureTouchAction.PanY" Swiped=""> <Card Background="@CurrentSlide.Background" TextColor="TextColor.White" Style="min-height: 260px; user-select: none;"> <CardBody Padding="Padding.Is5"> <Div Flex="Flex.Column.JustifyContent.Between" Style="min-height: 220px;"> <Div> <Badge Color="Color.Light" TextColor="TextColor.Dark" Pill> @( currentIndex + 1 ) / @slides.Count </Badge> <Heading Size="HeadingSize.Is2" Margin="Margin.Is4.FromTop.Is2.FromBottom"> @CurrentSlide.Title </Heading> <Paragraph TextColor="TextColor.White50"> @CurrentSlide.Description </Paragraph> </Div> <Div Flex="Flex.JustifyContent.Between.AlignItems.Center" Gap="Gap.Is3"> <Button Color="Color.Light" Outline Clicked=""> <Icon Name="IconName.ArrowLeft" /> </Button> <Badge Color="Color.Light" TextColor="TextColor.Dark" Pill> Swipe left or right </Badge> <Button Color="Color.Light" Outline Clicked=""> <Icon Name="IconName.ArrowRight" /> </Button> </Div> </Div> </CardBody> </Card> </Gestures>
@code { private readonly List<GallerySlide> slides = new List<GallerySlide> { new GallerySlide( "Overview", "Introduce key content one panel at a time.", Background.Primary ), new GallerySlide( "Details", "Let users move through content with direct touch interaction.", Background.Info ), new GallerySlide( "Summary", "Keep buttons available for mouse and keyboard users.", Background.Success ), }; private int currentIndex; private GallerySlide CurrentSlide => slides[currentIndex]; private Task OnSwiped( SwipeEventArgs eventArgs ) { if ( eventArgs.Direction == GestureDirection.Left ) ShowNext(); else if ( eventArgs.Direction == GestureDirection.Right ) ShowPrevious(); return Task.CompletedTask; } private void ShowPrevious() { currentIndex = currentIndex == 0 ? slides.Count - 1 : currentIndex - 1; } private void ShowNext() { currentIndex = currentIndex == slides.Count - 1 ? 0 : currentIndex + 1; } private class GallerySlide { public GallerySlide( string title, string description, Background background ) { Title = title; Description = description; Background = background; } public string Title { get; } public string Description { get; } public Background Background { get; } } }
Sidebar Toggle
Directional swipes can collapse or expand a side panel. Pair it withAnimate for a slide transition while keeping regular vertical page scrolling available with TouchAction="GestureTouchAction.PanY".
Navigation
Swipe left to collapse.
Content
Swipe right to expand the panel and swipe left to collapse it.
<Gestures Direction="GestureDirection.Horizontal" TouchAction="GestureTouchAction.PanY" Swiped=""> <Div Flex="Flex.Row" Border="Border.Is1.Rounded" Background="Background.Light" Padding="Padding.Is3" Height="Height.Px( 240 )" Style="user-select: none;"> <Div Flex="Flex.Row.Grow.Is1.AlignItems.Stretch" Gap="Gap.Is3"> <Animate Animation="Animations.SlideRight" Duration="" Trigger="AnimationTrigger.Render" Visible="" AnimateOnInitialRender="false" AnimatedSize="AnimatedSize.Width" Height="Height.Is100"> <Div Height="Height.Is100" Background="Background.Primary" TextColor="TextColor.White" Padding="Padding.Is3" Border="Border.Rounded" Width=""> <Heading Size="HeadingSize.Is6" Margin="Margin.Is0.FromBottom"> Navigation </Heading> <Paragraph TextColor="TextColor.White50" Margin="Margin.Is2.FromTop"> Swipe left to collapse. </Paragraph> </Div> </Animate> <Div Flex="Flex.Grow.Is1" Padding="Padding.Is2"> <Heading Size="HeadingSize.Is5" Margin="Margin.Is0.FromBottom"> Content </Heading> <Paragraph Margin="Margin.Is2.FromTop"> Swipe right to expand the panel and swipe left to collapse it. </Paragraph> <Button Color="Color.Primary" Outline Clicked=""> <Icon Name="@( sidebarExpanded ? IconName.Compress : IconName.Expand)" Margin="Margin.Is2.FromEnd" /> @( sidebarExpanded ? "Collapse" : "Expand" ) </Button> </Div> </Div> </Div> </Gestures>
@code { private static readonly TimeSpan SidebarAnimationDuration = TimeSpan.FromMilliseconds( 250 ); private static readonly IFluentSizing SidebarExpandedWidth = Width.Px( 160 ); private bool sidebarExpanded = true; private Task OnSwiped( SwipeEventArgs eventArgs ) { if ( eventArgs.Direction == GestureDirection.Left ) { sidebarExpanded = false; } else if ( eventArgs.Direction == GestureDirection.Right ) { sidebarExpanded = true; } return Task.CompletedTask; } private void ToggleSidebar() { sidebarExpanded = !sidebarExpanded; } }
Gesture Lifecycle
Use lifecycle events when the UI should update while the pointer is moving, for example a progress indicator, custom drawer motion, or swipe-to-dismiss preview.Swipe progress
Move horizontally inside this card to update the progress while the gesture is active.
<Gestures Direction="GestureDirection.Horizontal" TouchAction="GestureTouchAction.PanY" GestureStarted="" GestureMoved="" GestureEnded="" Swiped=""> <Card Border="Border.Is1.Rounded" Background="Background.Light" Style="user-select: none;"> <CardBody Padding="Padding.Is4"> <Heading Size="HeadingSize.Is5" Margin="Margin.Is0.FromBottom"> Swipe progress </Heading> <Paragraph TextColor="TextColor.Secondary" Margin="Margin.Is2.FromTop"> Move horizontally inside this card to update the progress while the gesture is active. </Paragraph> <Progress Value="" Color="" /> <Div Flex="Flex.Wrap" Gap="Gap.Is2" Margin="Margin.Is3.FromTop"> <Badge Color="Color.Primary" Pill>@state</Badge> <Badge Color="Color.Info" Pill>@direction</Badge> <Badge Color="Color.Secondary" Pill>Delta X: @deltaX</Badge> </Div> </CardBody> </Card> </Gestures>
@code { private int progress; private string state = "Waiting"; private string direction = "None"; private string deltaX = "0"; private Color progressColor = Color.Primary; private Task OnGestureStarted( GestureEventArgs eventArgs ) { state = "Started"; progress = 0; progressColor = Color.Primary; UpdateDetails( eventArgs ); return Task.CompletedTask; } private Task OnGestureMoved( GestureEventArgs eventArgs ) { state = "Moving"; progress = System.Math.Min( 100, System.Convert.ToInt32( System.Math.Abs( eventArgs.DeltaX ) ) ); UpdateDetails( eventArgs ); return Task.CompletedTask; } private Task OnGestureEnded( GestureEventArgs eventArgs ) { state = eventArgs.Canceled ? "Canceled" : "Ended"; UpdateDetails( eventArgs ); return Task.CompletedTask; } private Task OnSwiped( SwipeEventArgs eventArgs ) { progress = 100; progressColor = Color.Success; UpdateDetails( eventArgs ); return Task.CompletedTask; } private void UpdateDetails( GestureEventArgs eventArgs ) { direction = eventArgs.Direction.ToString(); deltaX = eventArgs.DeltaX.ToString( "0" ); } }
Touch action
TouchAction maps to the browser CSS touch-action behavior. For horizontal swipe areas inside a scrollable page, use GestureTouchAction.PanY so the page can still scroll vertically. For vertical swipe areas, use GestureTouchAction.PanX. Use GestureTouchAction.None only for surfaces where the component should own all touch movement.
Text selection
Gestures does not disable text selection. If a gesture surface contains text and is meant to be dragged or swiped as a single control, you may want to apply CSS such as user-select: none; to that surface. This prevents accidental text selection during mouse dragging on desktop. Avoid applying it to areas where users should be able to select or copy text.
API
Parameters
| Parameter | Description | Type | Default |
|---|---|---|---|
ChildContent |
Gets or sets the content that will be observed for gestures. |
RenderFragment | null |
Direction |
Gets or sets the directions that can produce swipe events. Possible values: |
GestureDirection | default(GestureDirection) |
Disabled |
Disables gesture handling. |
bool | false |
LongPressDuration |
Gets or sets the duration in milliseconds required to recognize a long press. |
int | 500 |
LongPressMoveTolerance |
Gets or sets the movement tolerance in pixels before a pending long press is canceled. |
double | 10 |
MoveThrottleInterval |
Gets or sets the minimum interval, in milliseconds, between GestureMoved callbacks. |
int | 50 |
SwipeThreshold |
Gets or sets the minimum swipe distance in pixels. |
double | 50 |
SwipeVelocityThreshold |
Gets or sets the minimum swipe velocity in pixels per millisecond. |
double | 0.3 |
TapMaximumDistance |
Gets or sets the maximum movement in pixels that can still be recognized as a tap. |
double | 10 |
TapMaximumDuration |
Gets or sets the maximum duration in milliseconds that can still be recognized as a tap. |
int | 300 |
TouchAction |
Gets or sets the browser touch-action behavior applied to the gestures element. Possible values: |
GestureTouchAction | GestureTouchAction.Auto |
Events
| Event | Description | Type |
|---|---|---|
GestureEnded |
Raised when a gesture ends or is canceled. |
EventCallback<GestureEventArgs> |
GestureMoved |
Raised while an active gesture moves. The callback is throttled by MoveThrottleInterval. |
EventCallback<GestureEventArgs> |
GestureStarted |
Raised when a gesture starts. |
EventCallback<GestureEventArgs> |
LongPressed |
Raised when an active gesture is held long enough to be recognized as a long press. |
EventCallback<LongPressEventArgs> |
Swiped |
Raised when a completed gesture is recognized as a swipe. |
EventCallback<SwipeEventArgs> |
Tapped |
Raised when a completed gesture is recognized as a tap. |
EventCallback<TapEventArgs> |
Methods
| Method | Description | Return | Parameters |
|---|---|---|---|
OnGestureEnded |
Handles a gesture end notification from the browser. | Task | GestureEventArgs eventArgs |
OnGestureMoved |
Handles a gesture move notification from the browser. | Task | GestureEventArgs eventArgs |
OnGestureStarted |
Handles a gesture start notification from the browser. | Task | GestureEventArgs eventArgs |
OnLongPressed |
Handles a long-press notification from the browser. | Task | LongPressEventArgs eventArgs |
OnSwiped |
Handles a swipe notification from the browser. | Task | SwipeEventArgs eventArgs |
OnTapped |
Handles a tap notification from the browser. | Task | TapEventArgs eventArgs |