Pressable
Touches are not delivered as raw taps. React Native negotiates a responder: when a finger goes
down, every view under it is asked in turn, from the outside in, whether it wants to claim the
touch, and then again from the inside out whether it will actually take it. That negotiation is
what lets a button inside a scroll view work correctly - the scroll view can claim a drag that
moves too far, and a nested pressable wins the touch over its container when both would otherwise
claim it. This package builds press, pressIn, pressOut and longPress on top of that same
negotiation, the way React Native's own Pressability does, rather than on plain touch listeners
that could not express any of it.
import { Pressable, TouchableOpacity } from '@ng-native/components';
<pressable><touchable-opacity> once they are in the component's importsPressable
<pressable> is the bare version of this: it renders a view and nothing else, but adds the press
machinery. pressed is a public signal, reachable through a template reference for styling that
depends on the press state without needing a class:
<pressable #p="pressable" [style.opacity]="p.pressed() ? 0.6 : 1" (press)="onTap()">
<text>Tap me</text>
</pressable><touchable-opacity> is the same machinery wired to React Native's own default look: it fades to
activeOpacity while pressed and eases back, using a CSS transition rather than a per-frame
tween, with React Native's own asymmetric timings (150ms in, 250ms out).
Props
Every pressable exposes disabled, hitSlop, pressRetentionOffset (how far a finger may wander
before the press is cancelled - separate from hitSlop, which is how far outside the view a touch
may start), delayLongPress, delayPressIn, delayPressOut, minPressDuration (the pressed
look is held at least this long even on the quickest tap), cancelable (whether a scrolling
ancestor may take the gesture away mid-press) and, on Android, androidRipple for a native
ripple.
Nested pressables
A pressable inside a pressable - a row with a delete button in it - needs nothing extra. The
negotiation elects the innermost pressable that wants the touch, so a tap on the button presses
the button and never the row. What does bubble past the button is the plain touch events,
(touchStart) and (touchEnd), which are not negotiated; a handler that wants an ancestor not to
see one calls $event.stopPropagation().
Composing pressability onto a component
A component that wants to be pressable rather than contain something pressable - a custom
button, say - composes PressBehavior through hostDirectives instead of wrapping a
<pressable>. That puts the whole responder negotiation on the component's own host node at the
cost of one native view rather than two, and the component calls contributeAccessibility to tell
the view primitive on that same host what role and state it should announce.
pressabledirective@ng-native/componentsimport { Pressable } from '@ng-native/components';and add Pressable to the component's imports A view that responds to presses. RN's Pressable , with the same configuration: hit slop, retention offset, press-in and press-out delays, long press, and an Android ripple.
No public members.
touchable-opacitycomponent@ng-native/componentsimport { TouchableOpacity } from '@ng-native/components';and add TouchableOpacity to the component's imports A pressable that dims while pressed, as RN's TouchableOpacity does.
Inputs
activeOpacitynumber = 0.2The opacity while pressed.