Skip to content

Utilities

SwipeTrap

Bit.BlazorUI

A SwipeTrap traps swipe gestures (touch, mouse or pen) on its container and raises start, move, end and trigger events carrying the swipe distance, direction, velocity, duration and pointer type. It supports axis locking (fixed or auto-detected), distance-based and velocity-based (flick) triggering, movement thresholds, event throttling and input filtering, which makes it the building block for swipeable panels, dismissible list items and other gesture-driven UIs.

Notes

The trap declares the axes it takes to the browser as a CSS touch-action, so a native scroll can never win the race against it: with no OrientationLock both axes belong to the trap and the page will not scroll over it, while a Horizontal or Vertical lock leaves the free axis to the browser. Pinch-zoom is always left to the browser. While a swipe is actually being trapped the root carries a bit-stp-swp class, which turns text selection off and is there to style the swiping state. A swipe is a path-based gesture, so pair it with a single-pointer alternative (a button, a menu item) to keep the feature operable without dragging.

Usage

Every example is live. Open its code to see exactly what produced the component running underneath.

Basic

Swipe or drag inside the container to see the live gesture data: the start point of the gesture, the distance moved on each axis (DiffX/DiffY), the velocity in pixels per millisecond, how long the gesture has been running (Duration), and the type of the pointer performing it (mouse, touch or pen). When the swipe passes the trigger point (a quarter of the container size by default), releasing it raises the OnTrigger event with the dominant swipe direction. A gesture the browser or the system takes over ends with IsCanceled set on the OnEnd event instead. Note the cursor while dragging: it comes from the bit-stp-swp class the trap carries for as long as it holds the gesture.

StartX:
StartY:
DiffX:
DiffY:
VelocityX:
VelocityY:
Duration: ms
PointerType:
IsCanceled:
---
Triggered? False
Trigger direction:
Trigger diffX:
Trigger diffY:

Trigger

Trigger sets how far a swipe must travel before releasing it raises OnTrigger. A value below 1 is a fraction of the container measured per axis (0.5 means half of its width horizontally and half of its height vertically), so the gesture scales with the element; a value of 1 or above is an absolute distance in pixels, which keeps the same feel whatever the container size. Both boxes below are the same size: the first needs half of it, the second only 80 pixels.

Trigger="0.5m"
(half of the container)
Direction:
DiffX:
DiffY:
Trigger="80m"
(80 pixels)
Direction:
DiffX:
DiffY:

Flick

TriggerVelocity recognizes flicks: a release faster than the given speed (here 0.5 pixels per millisecond) triggers even when the distance never reached the Trigger point, which is set deliberately far away at 0.9 of the container. The velocity is measured over the last moments of the gesture rather than averaged over all of it, so a swipe that drags slowly and then flicks still counts, while one that stops before release does not. Try a quick flick versus a slow drag:

Flicked? False
Flick direction:
Flick velocityX:
Flick velocityY:
Flick duration: ms

OrientationLock

OrientationLock restricts the trap to one axis. A Horizontal or Vertical lock is fixed for the whole gesture, whichever direction it starts in: the locked axis is the only one trapped (its default browser behavior, like scrolling, is prevented via a matching touch-action) and the only one reported, while the free axis is left to the browser and always reads zero. So a gesture along the free axis scrolls the page without moving the trap, and one that turns onto the locked axis is trapped from that moment on. Auto instead locks to whichever axis the gesture moves along first, trapping that one and zeroing the other for the rest of the gesture. Try swiping horizontally, vertically and diagonally on each container:

Horizontal lock
DiffX: 0
DiffY: 0
Vertical lock
DiffX: 0
DiffY: 0
Auto lock
DiffX: 0
DiffY: 0

Threshold & Throttle

Threshold is the distance a gesture must cover before the trap takes it over: below it the movement is still reported but nothing is trapped, which is what decides the axis of a diagonal swipe and keeps a small wobble from becoming one. Throttle limits how often OnMove reaches .NET, in milliseconds, which is worth setting when the handler does real work on every move; OnStart, OnEnd and OnTrigger are never throttled, so the final distance always arrives in full.

Threshold="30"
(the first 30px are free)
DiffX: 0
DiffY: 0
Throttle="200"
(at most one move per 200ms)
Moves: 0
DiffX: 0
DiffY: 0

Filtering

Control which gestures the trap responds to. TouchOnly ignores mouse drags, trapping only touch and pen swipes (handy when mouse users get buttons instead of gestures). SkipSelector ignores gestures that start on matching descendants, keeping nested interactive elements like inputs and sliders usable inside the trap:

TouchOnly
(mouse drags are ignored)
DiffX: 0
DiffY: 0
SkipSelector
DiffX: 0
DiffY: 0

Panel

A swipe-to-close panel: the OnMove event drags the panel with the finger (or mouse) so the surface follows the gesture, OnEnd snaps it back when the swipe was too short, and OnTrigger closes it once the swipe passes the trigger point. Open the panel and try to close it by swiping it to the left:

Title

Item1
Item2
Item3

List

Swipe-to-delete list rows, combining an absolute Trigger (60px), a Threshold (10px) that lets a small wobble scroll the list instead of opening a row, and a horizontal OrientationLock that leaves vertical scrolling to the browser while trapping only intentional horizontal swipes. Swipe each row to the right to trigger the delete action:

Delete
Item1
Delete
Item2
Delete
Item3
Delete
Item4
Delete
Item5
Delete
Item6
Delete
Item7
Delete
Item8
Delete
Item9
Delete
Item10

Advanced

An illustrative example of integrating this component into a straightforward mobile application: one trap drives two edge panels, using the move data for follow-the-finger dragging and the trigger direction for opening and closing each panel.

bit BlazorUI

Swipe left or right

Left Menu

Item1
Item2
Item3

Right Menu

Item1
Item2
Item3

API

Every parameter, public member, sub-class and enum this component exposes.

BitSwipeTrap parameters

Name Type Default value Description
ChildContent RenderFragment? null The content of the swipe trap.
OnStart EventCallback<BitSwipeTrapEventArgs> The event callback for when the swipe action starts on the container of the swipe trap.
OnMove EventCallback<BitSwipeTrapEventArgs> The event callback for when the swipe action moves on the container of the swipe trap.
OnEnd EventCallback<BitSwipeTrapEventArgs> The event callback for when the swipe action ends on the container of the swipe trap.
OnTrigger EventCallback<BitSwipeTrapTriggerArgs> The event callback for when the swipe action triggers based on the Trigger or TriggerVelocity constraints.
OrientationLock BitSwipeOrientation? null Specifies the orientation lock in which the swipe trap allows to trap the swipe actions. A Horizontal or Vertical lock is fixed for the whole gesture, whichever direction it starts in: the locked axis is the only one trapped and the only one reported, while the other axis keeps its default browser behavior (via a matching touch-action) and always reports zero. Auto instead locks to the first axis the gesture moves along.
SkipSelector string? null A CSS selector of descendant elements on which starting a swipe is ignored (e.g. inputs or nested interactive elements).
Threshold decimal? null The distance in pixels a gesture must cover before the swipe trap takes it over and stops the default behavior. It is also what resolves the axis a diagonal gesture is moving along (default is 0).
Throttle int? null The throttle time in milliseconds to apply a delay between periodic calls to raise the OnMove event (default is 0, meaning no throttling).
TouchOnly bool false Ignores mouse swipes, trapping only touch (and pen) gestures.
Trigger decimal? null The swiping point to trigger and call the OnTrigger event: either a fraction of the element's width/height (values less than 1) or an absolute value in pixels (default is 0.25m).
TriggerVelocity decimal? null The swiping velocity in pixels per millisecond that triggers and calls the OnTrigger event on release (a flick), even if the swiping distance has not reached the Trigger point (default is 0, meaning disabled).

BitComponentBase parameters

Name Type Default value Description
AriaLabel string? null Gets or sets the accessible label for the component, used by assistive technologies.
Class string? null Gets or sets the CSS class name(s) to apply to the rendered element.
Dir BitDir? null Gets or sets the text directionality for the component's content.
ForceAnimation bool false Gets or sets a value indicating whether the component's animations play at their full duration even when reduced motion is requested.
HtmlAttributes Dictionary<string, object> new Dictionary<string, object>() Captures additional HTML attributes to be applied to the rendered element, in addition to the component's parameters.
Id string? null Gets or sets the unique identifier for the component's root element.
IsEnabled bool true Gets or sets a value indicating whether the component is enabled and can respond to user interaction.
Style string? null Gets or sets the CSS style string to apply to the rendered element.
TabIndex string? null Gets or sets the tab order index for the component when navigating with the keyboard.
Visibility BitVisibility BitVisibility.Visible Gets or sets the visibility state (visible, hidden, or collapsed) of the component.

BitComponentBase public members

Name Type Default value Description
UniqueId Guid Guid.NewGuid() Gets the readonly unique identifier for the component's root element, assigned when the component instance is constructed.
RootElement ElementReference Gets the reference to the root HTML element associated with this component.

BitSwipeTrapEventArgs properties

The event arguments of the SwipeTrap events.

Name Type Default value Description
StartX decimal 0 The horizontal start point of the swipe action in pixels, relative to the viewport.
StartY decimal 0 The vertical start point of the swipe action in pixels, relative to the viewport.
DiffX decimal 0 The horizontal difference of swipe action in pixels.
DiffY decimal 0 The vertical difference of swipe action in pixels.
VelocityX decimal 0 The horizontal velocity of the swipe action in pixels per millisecond.
VelocityY decimal 0 The vertical velocity of the swipe action in pixels per millisecond.
PointerType string? null The type of the pointer that performed the swipe action: "mouse", "touch" or "pen".
IsCanceled bool false Whether the swipe action ended by being canceled (e.g. the browser took the gesture over) instead of a normal release. Only meaningful in the OnEnd event.
Duration decimal 0 The elapsed time of the swipe action in milliseconds, measured from the moment it started.

BitSwipeTrapTriggerArgs properties

The event arguments of the SwipeTrap trigger event.

Name Type Default value Description
Direction BitSwipeDirection The swipe direction in which the action triggered.
DiffX decimal 0 The horizontal difference of swipe action in pixels.
DiffY decimal 0 The vertical difference of swipe action in pixels.
VelocityX decimal 0 The horizontal velocity of the swipe action in pixels per millisecond.
VelocityY decimal 0 The vertical velocity of the swipe action in pixels per millisecond.
PointerType string? null The type of the pointer that performed the swipe action: "mouse", "touch" or "pen".
Duration decimal 0 The elapsed time of the swipe action in milliseconds, measured from the moment it started.

BitSwipeOrientation enum

Name Value Description
None 0 No orientation lock for the swipe trap.
Horizontal 1 Horizontal orientation lock of trapping the swipe action.
Vertical 2 Vertical orientation lock of trapping the swipe action.
Auto 3 Locks the trap to the first orientation the gesture moves along, trapping that axis and zeroing the other.

BitSwipeDirection enum

Name Value Description
Right 0 Swipe to right direction.
Left 1 Swipe to left direction.
Top 2 Swipe to top direction.
Bottom 3 Swipe to bottom direction.

BitVisibility enum

Name Value Description
Visible 0 The content of the component is visible.
Hidden 1 The content of the component is hidden, but the space it takes on the page remains (visibility:hidden).
Collapsed 2 The component is hidden (display:none).

BitDir enum

Name Value Description
Ltr 0 Ltr (left to right) is to be used for languages that are written from the left to the right (like English).
Rtl 1 Rtl (right to left) is to be used for languages that are written from the right to the left (like Arabic).
Auto 2 Auto lets the user agent decide. It uses a basic algorithm as it parses the characters inside the element until it finds a character with a strong directionality, then applies that directionality to the whole element.

Feedback

Found a mistake, a gap, or something that could be clearer? Every page and every component is one click from its source.