Press
Track pointer and keyboard press state on any element.
Why use this atom?
- Unified press tracking for pointer (mouse, touch, pen) and keyboard (Enter, Space)
- Uses
pointermoveinstead ofpointerleavefor iOS Safari compatibility - Tracks active key to prevent mismatched keyup releases
- Skips editable targets (inputs, textareas, contenteditable) for keyboard press
- Emits
pressStartandpressEndevents for side effects - Configurable long-press via
delayanddistanceThresholdinputs
Import
import {AtomPress} from '@terse-ui/atoms/press';Usage
<button atomPress>Hold me</button>When the element is pressed via pointer or keyboard, data-press is set. It is removed when the press ends.
Events
<button atomPress (atomPressStart)="onStart()" (atomPressEnd)="onEnd()">
Press me
</button>Template reference
<button atomPress #p="atomPress">
{{ p.isPressed() ? 'Pressing...' : 'Press me' }}
</button>Disabling
<button atomPress [atomPressDisabled]="true">No press tracking</button>As a host directive
@Directive({
selector: '[myButton]',
hostDirectives: [AtomPress, AtomHover, AtomFocus],
})
export class MyButton {}Styling
[atomPress][data-press] {
transform: scale(0.98);
opacity: 0.9;
}Pointer handling
On pointerdown, the directive attaches global pointerup, pointercancel, and pointermove listeners on the document. The pointermove handler uses getBoundingClientRect() to detect when the pointer exits the element bounds — this is more reliable than pointerleave on iOS Safari. All global listeners are cleaned up on release and on destroy.
Long press
Enable long-press detection by setting a delay in milliseconds:
<button atomPress [atomPressDelay]="500" (atomPressLongPress)="onLongPress($event)">
Hold me
</button>The longPress output fires after the delay elapses if the pointer hasn't moved beyond distanceThreshold (default 10px). Set distanceThreshold to false to disable movement cancellation:
<button
atomPress
[atomPressDelay]="800"
[atomPressDistanceThreshold]="false"
(atomPressLongPress)="showContextMenu($event)"
>
Long press for options
</button>When delay is 0 (the default), long-press detection is inactive and no longPress events are emitted. The instant press behavior (isPressed, data-press, pressStart, pressEnd) always works regardless of the delay setting.
Keyboard handling
Enter and Space trigger press on keydown. The directive tracks the active key to prevent a mismatched keyup (e.g., pressing Enter then releasing Space) from ending the press. Press is also reset on blur. Editable targets (text inputs, textareas, contenteditable) are ignored to avoid interfering with typing.
API Reference
AtomPress
| Selector | [atomPress] |
| Exported as | atomPress |
| Data attributes | data-press |
Inputs
| Input | Type | Default | Description |
|---|---|---|---|
atomPressDisabled | boolean | Disables press tracking. | |
atomPressDelay | number | Long-press delay in milliseconds. When greater than 0, enables long-press detection. | |
atomPressDistanceThreshold | number | false | Max pointer movement (px) before cancelling a long press. Set to false to disable. |
Outputs
| Output | Type | Description |
|---|---|---|
atomPressDisabledChange | boolean | Disables press tracking. |
atomPressStart | void | Emits when a press begins. |
atomPressEnd | void | Emits when a press ends. |
atomPressLongPress | PointerEvent | Emits the PointerEvent when a long press is detected. |
Properties
| Property | Type | Description |
|---|---|---|
isPressed | Signal<boolean> (readonly) | Whether the element is currently being pressed. |
dataPressAttr | Signal<"" | null> (readonly) |