Skip to content

Utilities

SwipeTrap

Bit.BlazorUIGestureSwipeable

SwipeTrap traps swipe gestures - touch, mouse or pen - on its content and reports them as start, move, end and trigger events carrying distance, velocity, duration and direction. It locks an axis, triggers by distance or by a flick, filters what it responds to, and lets the arrow keys trigger it as the keyboard's alternative.

Notes

A swipe is a path-based gesture, so pair it with a control that needs no dragging (a button, a menu item), and turn on KeyboardTrigger for the keyboard (WCAG 2.2 SC 2.5.1, 2.5.7 and 2.1.1). The control is also what a screen reader reaches: in browse mode it keeps the arrow keys for itself. The trap declares the axes it takes as a CSS touch-action: with no OrientationLock the page does not scroll over it, a Horizontal or Vertical lock leaves the other axis to the browser, a disabled trap leaves both, and pinch-zoom is always the browser's. While a swipe is trapped the root carries the bit-stp-swp class.

Usage

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

Basic

Swipe or drag inside the box. OnStart, OnMove and OnEnd report the start point, the distance (DiffX/DiffY), the velocity in px/ms, the Duration and the PointerType; a gesture the browser takes over ends with IsCanceled. Released past a quarter of the box, it raises OnTrigger with the dominant Direction.

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

Trigger

Trigger is how far a swipe must travel before its release raises OnTrigger: below 1 it is a fraction of the box per axis, from 1 up it is pixels. TriggerVelocity (px/ms) also triggers a quick flick that never got that far - the third box needs 90% of its width, or a flick.

Trigger="0.5m"
(half of the box)
Direction:
DiffX:
DiffY:
Trigger="80m"
(80 pixels)
Direction:
DiffX:
DiffY:
TriggerVelocity="0.5m"
(a flick)
Direction:
VelocityX:
VelocityY:

OrientationLock

Horizontal and Vertical trap one axis for the whole gesture and report zero on the other, which stays the browser's - a swipe along it scrolls the page. Auto locks to whichever axis the gesture moves along first. Try each box horizontally, vertically and diagonally.

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

Threshold & Throttle

Threshold is the distance a gesture covers before the trap takes it over - a wobble below it is left alone. Throttle (ms) limits how often OnMove reaches .NET; OnStart, OnEnd and OnTrigger are never throttled.

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

Filtering

TouchOnly ignores mouse drags, trapping touch and pen only. SkipSelector ignores the gestures that start on matching descendants, so an input or a slider inside the trap keeps working. A disabled trap (Disabled) takes nothing and lets the page scroll over it.

TouchOnly
(mouse drags are ignored)
DiffX: 0
DiffY: 0
SkipSelector
DiffX: 0
DiffY: 0
Disabled
(nothing is trapped)
Moves: 0

Keyboard

KeyboardTrigger makes the trap a tab stop whose arrow keys act as a swipe in their direction, raising OnTrigger with a PointerType of "keyboard". A Horizontal or Vertical lock limits the keys to its axis, and the keys are named in aria-keyshortcuts. Name the trap with AriaLabel. Escape cancels a swipe in progress: OnEnd reports it with IsCanceled and nothing triggers.

Left: snooze - Right: archive
Last action:
PointerType:
Last swipe:

List

Swipe-to-delete rows: OnMove drags the row, OnEnd snaps it back, and OnTrigger asks to delete it once it has been swiped 60px to the right. A horizontal lock and a 10px Threshold keep the list scrolling vertically. The delete button is the single-pointer alternative WCAG 2.5.7 asks for, and the keyboard's too; a swipe that starts on it does not click it.

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

Advanced

One trap drives two edge panels of a mobile layout: the move data drags them with the finger and the trigger direction opens and closes them. The header buttons do the same without a swipe, and so do the arrow keys once the screen has the focus; a closed panel is inert.

bit BlazorUI

Swipe left or right

Left Menu

Item1
Item2
Item3

Right Menu

Item1
Item2
Item3

Cascading parameters

BitParams hands a BitSwipeTrapParams to every SwipeTrap under it. The values are defaults: a trap keeps whatever it sets itself. The content and the callbacks stay per instance.

From BitParams
(horizontal, 60px, arrow keys)
Direction:
Its own vertical lock
(the rest from BitParams)
Direction:

Style & Class

Style and Class land on the trap's root; the bit-stp-swp class marks it while a swipe is trapped. The public --bit-SwipeTrap-* variables inherit, so one set on :root restyles every trap and one set on Style restyles that one: here the cursors and the focus ring.

Style
Class (swipe me)
CSS variables (hover, swipe, Tab)

RTL

Directions are physical, for the swipe and the arrow keys alike: Dir sets the direction of the content, not of the gesture. Where a direction means start or end, map it yourself - here the end of the line is on the left.

راست: تعویق - چپ: بایگانی
آخرین اقدام:

CSS variables

The public custom properties this component reads off its root, for what no parameter covers.

Every variable is read with a fallback and never declared by the component, so it inherits like any other custom property: set one on :root (or in a [bit-theme] block) to restyle every instance, on any ancestor to restyle the ones inside it, or on the Style of one instance to restyle that one alone. Leave a variable unset and the component falls back to the theme token beside it.

BitSwipeTrap CSS variables

Name Default value Description
--bit-SwipeTrap-cursor inherit Pointer cursor over the trap at rest, e.g. grab.
--bit-SwipeTrap-swiping-cursor grabbing Pointer cursor while a swipe is being trapped.
--bit-SwipeTrap-focus-color --bit-clr-pri-focus Focus ring color of a trap the keyboard can reach (KeyboardTrigger).

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.
KeyboardTrigger bool false Lets the arrow keys raise OnTrigger in their own direction while the trap itself has the focus. Makes the trap a tab stop, names the keys in aria-keyshortcuts and honors a Horizontal or Vertical OrientationLock. The event carries zero distances and a PointerType of "keyboard".
OnStart EventCallback<BitSwipeTrapEventArgs> Raised when a swipe starts on the trap.
OnMove EventCallback<BitSwipeTrapEventArgs> Raised while a swipe moves, at most once per Throttle milliseconds.
OnEnd EventCallback<BitSwipeTrapEventArgs> Raised when a swipe is released, or canceled (IsCanceled) by the browser, by leaving the trap before it was trapped, or by Escape.
OnTrigger EventCallback<BitSwipeTrapTriggerArgs> Raised on the release of a swipe that passed Trigger or was flicked faster than TriggerVelocity, and on an arrow key with KeyboardTrigger.
OrientationLock BitSwipeOrientation? null Locks the trap to one axis. Horizontal and Vertical trap and report only that axis for the whole gesture, leaving the other to the browser (it reads zero); Auto locks to the axis the gesture moves along first.
SkipSelector string? null A CSS selector of descendants on which a swipe never starts, such as inputs or nested sliders.
Threshold decimal? null The distance in pixels a gesture covers before the trap takes it over; it also decides the axis of a diagonal one. Defaults to 0.
Throttle int? null The least time in milliseconds between two OnMove events; the latest move of a window still arrives when it closes. Defaults to 0 (no throttling).
TouchOnly bool false Ignores mouse swipes, trapping only touch and pen gestures.
Trigger decimal? null How far a swipe travels before its release triggers: a fraction of the trap's size per axis below 1, pixels from 1 up. Defaults to 0.25.
TriggerVelocity decimal? null The release velocity in px/ms that triggers a flick short of Trigger. Defaults to 0 (off).

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.
Disabled bool false Gets or sets a value indicating whether the component is disabled and cannot respond to user interaction.
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.
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 was canceled (the browser took it over, it left the trap before being trapped, or Escape was pressed) rather than released. Only meaningful in OnEnd.
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 BitPlacement The swipe direction in which the action triggered. It is always one of the physical four - Top, Bottom, Left or Right - read off the screen rather than off the reading direction.
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" - or "keyboard" for an arrow key with KeyboardTrigger.
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.

BitPlacement enum

Name Value Description
Top 0 The top edge.
Bottom 1 The bottom edge.
Start 2 The edge the reading direction starts from - the left in LTR, the right in RTL. On the vertical axis, which does not turn around, it is the top.
End 3 The edge the reading direction ends at - the right in LTR, the left in RTL. On the vertical axis, which does not turn around, it is the bottom.
Left 4 The left edge, in both reading directions.
Right 5 The right edge, in both reading directions.
Center 6 The middle of the axis, against neither edge.
TopAndBottom 7 Both edges of the block axis at once.
StartAndEnd 8 Both edges of the inline axis at once, following the reading direction the way Start and End do.

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.