navius

Gestures

A press-and-hover micro-interaction pack. The CSS tier scales on press and lifts on hover with zero JavaScript; the runtime tier adds keyboard parity and coarse start/end callbacks to C#.

CSS tier

Two classes, both timed with the snappy spring. .motion-press uses :active, which also covers keyboard activation on a real <button>. .motion-hover sits behind @media (hover: hover), so emulated touch hover never triggers a stuck lift.

Class Trigger Variable (default)
.motion-press:active--navius-motion-press-scale (0.97)
.motion-hover:hover, hover-capable pointers only--navius-motion-hover-lift (2px)

Splat helpers

Motion.Press and Motion.Hover return the class plus the custom-property override as a dictionary to splat with @attributes. Splat instead of a literal class (last wins), or write the class and the --navius-motion-* variable directly.

Member Returns Effect
Motion.Press(double scale = 0.97)IReadOnlyDictionary<string, object>motion-press with the press-scale variable set.
Motion.Hover(double lift = 2)IReadOnlyDictionary<string, object>motion-hover with the hover-lift variable set (pixels).

Runtime gestures

For keyboard parity and event callbacks, bind CreateGestureAsync. The animation runs JS-side (one WAAPI tween at a time, snapshotting the live transform so changes flow smoothly); only coarse start/end edges cross to C#. Pass a DotNetObjectReference to receive them.

Bind a press or hover gesture (kind is press or hover). The overload with a callback reports edges to it. Returns a MotionGesture; dispose it to remove the listeners.

Prop Type Default
CreateGestureAsync(ElementReference element, string kind, GestureOptions options) Task<MotionGesture> -
CreateGestureAsync<T>(ElementReference element, string kind, DotNetObjectReference<T> callback, GestureOptions options) Task<MotionGesture> -
MotionPrograms.Gesture(Spring? spring = null, double pressScale = 0.97, double hoverLift = 2) GestureOptions -

Serialized to the executor. Timing is the baked spring the gesture animates with; build it with MotionPrograms.Gesture.

Prop Type Default
DurationMs double -
Easing string -
PressScale double 0.97
HoverLift double 2
ReduceMotion string "user"
Callback (JSInvokable) Fires when
OnGestureStart(string kind)Press or hover begins; kind is "press" or "hover".
OnGestureEnd(bool success)Gesture ends; success is false when cancelled (blur, or the pointer left the target).

Interaction semantics

The runtime press mirrors a real activation, not just a pointer-down. It engages on the primary button of the primary pointer only, so right-clicks and secondary touches are ignored. Keyboard Enter presses and releases the element in parity with a pointer, and a blur while the key is held cancels the press. Hover ignores pointerType === "touch", so a tap never leaves the element hovered.

Key Description
Enter Presses the element on keydown and releases it on keyup, in parity with a pointer press. A blur while held cancels.

Under prefers-reduced-motion (or ReduceMotion = "always") the transform animations are skipped, but the start and end callbacks still fire: behaviour is not decoration. Set ReduceMotion = "never" to opt a single gesture out.