@ng-native/components 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +78 -1
- package/dist/activity-indicator.d.ts +41 -0
- package/dist/activity-indicator.js +66 -0
- package/dist/activity-indicator.js.map +1 -0
- package/dist/animated-style.d.ts +31 -0
- package/dist/animated-style.js +102 -0
- package/dist/animated-style.js.map +1 -0
- package/dist/animated.d.ts +125 -0
- package/dist/animated.js +538 -0
- package/dist/animated.js.map +1 -0
- package/dist/animation.d.ts +40 -0
- package/dist/animation.js +20 -0
- package/dist/animation.js.map +1 -0
- package/dist/animations-web.d.ts +8 -0
- package/dist/animations-web.js +31 -0
- package/dist/animations-web.js.map +1 -0
- package/dist/animations.d.ts +7 -0
- package/dist/animations.js +58 -0
- package/dist/animations.js.map +1 -0
- package/dist/controlled-model.d.ts +33 -0
- package/dist/controlled-model.js +47 -0
- package/dist/controlled-model.js.map +1 -0
- package/dist/easing.d.ts +21 -0
- package/dist/easing.js +50 -0
- package/dist/easing.js.map +1 -0
- package/dist/events.d.ts +169 -0
- package/dist/events.js +2 -0
- package/dist/events.js.map +1 -0
- package/dist/gesture-backend.d.ts +26 -0
- package/dist/gesture-backend.js +14 -0
- package/dist/gesture-backend.js.map +1 -0
- package/dist/gesture-dispatch.d.ts +67 -0
- package/dist/gesture-dispatch.js +106 -0
- package/dist/gesture-dispatch.js.map +1 -0
- package/dist/gestures.d.ts +23 -0
- package/dist/gestures.js +164 -0
- package/dist/gestures.js.map +1 -0
- package/dist/height-index.d.ts +31 -0
- package/dist/height-index.js +80 -0
- package/dist/height-index.js.map +1 -0
- package/dist/image-background.d.ts +32 -0
- package/dist/image-background.js +80 -0
- package/dist/image-background.js.map +1 -0
- package/dist/image.d.ts +79 -0
- package/dist/image.js +155 -0
- package/dist/image.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/input-accessory-view.d.ts +16 -0
- package/dist/input-accessory-view.js +29 -0
- package/dist/input-accessory-view.js.map +1 -0
- package/dist/keyboard-avoiding-view.d.ts +79 -0
- package/dist/keyboard-avoiding-view.js +172 -0
- package/dist/keyboard-avoiding-view.js.map +1 -0
- package/dist/keyboard-dock.d.ts +126 -0
- package/dist/keyboard-dock.js +327 -0
- package/dist/keyboard-dock.js.map +1 -0
- package/dist/keyboard-taps.d.ts +12 -0
- package/dist/keyboard-taps.js +51 -0
- package/dist/keyboard-taps.js.map +1 -0
- package/dist/modal.d.ts +56 -0
- package/dist/modal.js +102 -0
- package/dist/modal.js.map +1 -0
- package/dist/native-gesture.d.ts +21 -0
- package/dist/native-gesture.js +56 -0
- package/dist/native-gesture.js.map +1 -0
- package/dist/native-ref.d.ts +7 -0
- package/dist/native-ref.js +13 -0
- package/dist/native-ref.js.map +1 -0
- package/dist/pressable.d.ts +220 -0
- package/dist/pressable.js +484 -0
- package/dist/pressable.js.map +1 -0
- package/dist/reanimated.d.ts +19 -0
- package/dist/reanimated.js +111 -0
- package/dist/reanimated.js.map +1 -0
- package/dist/refresh-control.d.ts +50 -0
- package/dist/refresh-control.js +103 -0
- package/dist/refresh-control.js.map +1 -0
- package/dist/safe-area-provider.d.ts +11 -0
- package/dist/safe-area-provider.js +70 -0
- package/dist/safe-area-provider.js.map +1 -0
- package/dist/safe-area-view.d.ts +22 -0
- package/dist/safe-area-view.js +77 -0
- package/dist/safe-area-view.js.map +1 -0
- package/dist/safe-area.d.ts +12 -0
- package/dist/safe-area.js +27 -0
- package/dist/safe-area.js.map +1 -0
- package/dist/scroll-view-props.d.ts +89 -0
- package/dist/scroll-view-props.js +153 -0
- package/dist/scroll-view-props.js.map +1 -0
- package/dist/scroll-view.d.ts +95 -0
- package/dist/scroll-view.js +181 -0
- package/dist/scroll-view.js.map +1 -0
- package/dist/section-list.d.ts +146 -0
- package/dist/section-list.js +300 -0
- package/dist/section-list.js.map +1 -0
- package/dist/sticky-headers.d.ts +41 -0
- package/dist/sticky-headers.js +118 -0
- package/dist/sticky-headers.js.map +1 -0
- package/dist/swipe-refresh-layout.d.ts +51 -0
- package/dist/swipe-refresh-layout.js +162 -0
- package/dist/swipe-refresh-layout.js.map +1 -0
- package/dist/switch.d.ts +54 -0
- package/dist/switch.js +110 -0
- package/dist/switch.js.map +1 -0
- package/dist/template-slot.d.ts +18 -0
- package/dist/template-slot.js +30 -0
- package/dist/template-slot.js.map +1 -0
- package/dist/text-input.d.ts +168 -0
- package/dist/text-input.js +312 -0
- package/dist/text-input.js.map +1 -0
- package/dist/text.d.ts +70 -0
- package/dist/text.js +111 -0
- package/dist/text.js.map +1 -0
- package/dist/touchable-opacity.d.ts +36 -0
- package/dist/touchable-opacity.js +76 -0
- package/dist/touchable-opacity.js.map +1 -0
- package/dist/transforms.d.ts +2 -0
- package/dist/transforms.js +17 -0
- package/dist/transforms.js.map +1 -0
- package/dist/view-base.d.ts +332 -0
- package/dist/view-base.js +534 -0
- package/dist/view-base.js.map +1 -0
- package/dist/view.d.ts +12 -0
- package/dist/view.js +18 -0
- package/dist/view.js.map +1 -0
- package/dist/virtual-list.d.ts +530 -0
- package/dist/virtual-list.js +1150 -0
- package/dist/virtual-list.js.map +1 -0
- package/dist/worklet-scroll.d.ts +13 -0
- package/dist/worklet-scroll.js +49 -0
- package/dist/worklet-scroll.js.map +1 -0
- package/dist/worklet-style.d.ts +13 -0
- package/dist/worklet-style.js +47 -0
- package/dist/worklet-style.js.map +1 -0
- package/dist/worklets.d.ts +89 -0
- package/dist/worklets.js +42 -0
- package/dist/worklets.js.map +1 -0
- package/dist/written-props.d.ts +6 -0
- package/dist/written-props.js +180 -0
- package/dist/written-props.js.map +1 -0
- package/package.json +88 -3
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The state machine between a gesture's raw events and the callbacks it declared.
|
|
3
|
+
*
|
|
4
|
+
* This is what `useAnimatedGesture` does with hooks in react-native-gesture-handler, and the only
|
|
5
|
+
* part of a gesture we write rather than borrow. It is here, apart from the library, so it can be
|
|
6
|
+
* driven by a test: on a device it is serialised onto the UI runtime and a mistake in it is a
|
|
7
|
+
* callback that silently never runs.
|
|
8
|
+
*
|
|
9
|
+
* The numbers below are the ones on the wire. They are the library's `State` and `TouchEventType`,
|
|
10
|
+
* restated rather than imported because importing them would reach React Native's Flow source and
|
|
11
|
+
* make this package unloadable in Node - and because they are a protocol between native and us,
|
|
12
|
+
* not an API surface: native puts these integers in the event.
|
|
13
|
+
*/
|
|
14
|
+
/** `State` in react-native-gesture-handler. */
|
|
15
|
+
export declare const GESTURE_STATE: {
|
|
16
|
+
readonly UNDETERMINED: 0;
|
|
17
|
+
readonly FAILED: 1;
|
|
18
|
+
readonly BEGAN: 2;
|
|
19
|
+
readonly CANCELLED: 3;
|
|
20
|
+
readonly ACTIVE: 4;
|
|
21
|
+
readonly END: 5;
|
|
22
|
+
};
|
|
23
|
+
/** `TouchEventType` in react-native-gesture-handler. */
|
|
24
|
+
export declare const TOUCH_EVENT: {
|
|
25
|
+
readonly UNDETERMINED: 0;
|
|
26
|
+
readonly DOWN: 1;
|
|
27
|
+
readonly MOVE: 2;
|
|
28
|
+
readonly UP: 3;
|
|
29
|
+
readonly CANCELLED: 4;
|
|
30
|
+
};
|
|
31
|
+
/** Lets a touch callback accept or reject the gesture from the UI thread. */
|
|
32
|
+
export interface GestureStateManager {
|
|
33
|
+
begin(): void;
|
|
34
|
+
activate(): void;
|
|
35
|
+
fail(): void;
|
|
36
|
+
end(): void;
|
|
37
|
+
}
|
|
38
|
+
/** A gesture's declared callbacks, as the library leaves them once it has prepared the gesture. */
|
|
39
|
+
export interface GestureCallbacks {
|
|
40
|
+
handlerTag: number;
|
|
41
|
+
onBegin?: (event: object) => void;
|
|
42
|
+
onStart?: (event: object) => void;
|
|
43
|
+
onUpdate?: (event: object) => void;
|
|
44
|
+
onChange?: (event: object) => void;
|
|
45
|
+
onEnd?: (event: object, success: boolean) => void;
|
|
46
|
+
onFinalize?: (event: object, success: boolean) => void;
|
|
47
|
+
onTouchesDown?: (event: object, manager: GestureStateManager) => void;
|
|
48
|
+
onTouchesMove?: (event: object, manager: GestureStateManager) => void;
|
|
49
|
+
onTouchesUp?: (event: object, manager: GestureStateManager) => void;
|
|
50
|
+
onTouchesCancelled?: (event: object, manager: GestureStateManager) => void;
|
|
51
|
+
changeEventCalculator?: (current: object, previous?: object) => object;
|
|
52
|
+
}
|
|
53
|
+
/** What native sends. Which of the three kinds it is, is told by which fields are present. */
|
|
54
|
+
export interface GestureEvent {
|
|
55
|
+
handlerTag: number;
|
|
56
|
+
state?: number;
|
|
57
|
+
oldState?: number;
|
|
58
|
+
eventType?: number;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Build the worklet that receives a view's gesture events.
|
|
62
|
+
*
|
|
63
|
+
* `createManager` is the library's `GestureStateManager.create`, passed in rather than imported
|
|
64
|
+
* for the reason the constants are restated. It has to be a worklet itself: everything this
|
|
65
|
+
* closure holds is serialised onto the UI runtime with it.
|
|
66
|
+
*/
|
|
67
|
+
export declare function gestureDispatcher(callbacks: readonly GestureCallbacks[], createManager: (handlerTag: number) => GestureStateManager): (event: GestureEvent) => void;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The state machine between a gesture's raw events and the callbacks it declared.
|
|
3
|
+
*
|
|
4
|
+
* This is what `useAnimatedGesture` does with hooks in react-native-gesture-handler, and the only
|
|
5
|
+
* part of a gesture we write rather than borrow. It is here, apart from the library, so it can be
|
|
6
|
+
* driven by a test: on a device it is serialised onto the UI runtime and a mistake in it is a
|
|
7
|
+
* callback that silently never runs.
|
|
8
|
+
*
|
|
9
|
+
* The numbers below are the ones on the wire. They are the library's `State` and `TouchEventType`,
|
|
10
|
+
* restated rather than imported because importing them would reach React Native's Flow source and
|
|
11
|
+
* make this package unloadable in Node - and because they are a protocol between native and us,
|
|
12
|
+
* not an API surface: native puts these integers in the event.
|
|
13
|
+
*/
|
|
14
|
+
/** `State` in react-native-gesture-handler. */
|
|
15
|
+
export const GESTURE_STATE = {
|
|
16
|
+
UNDETERMINED: 0,
|
|
17
|
+
FAILED: 1,
|
|
18
|
+
BEGAN: 2,
|
|
19
|
+
CANCELLED: 3,
|
|
20
|
+
ACTIVE: 4,
|
|
21
|
+
END: 5,
|
|
22
|
+
};
|
|
23
|
+
/** `TouchEventType` in react-native-gesture-handler. */
|
|
24
|
+
export const TOUCH_EVENT = {
|
|
25
|
+
UNDETERMINED: 0,
|
|
26
|
+
DOWN: 1,
|
|
27
|
+
MOVE: 2,
|
|
28
|
+
UP: 3,
|
|
29
|
+
CANCELLED: 4,
|
|
30
|
+
};
|
|
31
|
+
function stateChange(gesture, event, memory) {
|
|
32
|
+
'worklet';
|
|
33
|
+
const state = event.state;
|
|
34
|
+
// A state-change event is a transition, so `oldState !== state` always holds and the only part
|
|
35
|
+
// of the old state that matters is whether the gesture had gone active: that is what decides
|
|
36
|
+
// between an end and a finalize alone.
|
|
37
|
+
const wasActive = event.oldState === GESTURE_STATE.ACTIVE;
|
|
38
|
+
if (state === GESTURE_STATE.BEGAN) {
|
|
39
|
+
gesture.onBegin?.(event);
|
|
40
|
+
}
|
|
41
|
+
else if (state === GESTURE_STATE.ACTIVE) {
|
|
42
|
+
gesture.onStart?.(event);
|
|
43
|
+
memory.previous[gesture.handlerTag] = undefined;
|
|
44
|
+
}
|
|
45
|
+
else if (state === GESTURE_STATE.END ||
|
|
46
|
+
state === GESTURE_STATE.FAILED ||
|
|
47
|
+
state === GESTURE_STATE.CANCELLED) {
|
|
48
|
+
const succeeded = state === GESTURE_STATE.END;
|
|
49
|
+
if (wasActive)
|
|
50
|
+
gesture.onEnd?.(event, succeeded);
|
|
51
|
+
gesture.onFinalize?.(event, succeeded);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function update(gesture, event, memory) {
|
|
55
|
+
'worklet';
|
|
56
|
+
gesture.onUpdate?.(event);
|
|
57
|
+
// `onChange` is `onUpdate` measured against the event before it, which is what makes a drag
|
|
58
|
+
// accumulate rather than jump. The calculator belongs to the gesture; only the memory is ours.
|
|
59
|
+
if (gesture.onChange && gesture.changeEventCalculator) {
|
|
60
|
+
gesture.onChange(gesture.changeEventCalculator(event, memory.previous[gesture.handlerTag]));
|
|
61
|
+
memory.previous[gesture.handlerTag] = event;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function touches(gesture, event, memory, createManager) {
|
|
65
|
+
'worklet';
|
|
66
|
+
let manager = memory.managers[gesture.handlerTag];
|
|
67
|
+
if (!manager) {
|
|
68
|
+
manager = createManager(gesture.handlerTag);
|
|
69
|
+
memory.managers[gesture.handlerTag] = manager;
|
|
70
|
+
}
|
|
71
|
+
const type = event.eventType;
|
|
72
|
+
if (type === TOUCH_EVENT.DOWN)
|
|
73
|
+
gesture.onTouchesDown?.(event, manager);
|
|
74
|
+
else if (type === TOUCH_EVENT.MOVE)
|
|
75
|
+
gesture.onTouchesMove?.(event, manager);
|
|
76
|
+
else if (type === TOUCH_EVENT.UP)
|
|
77
|
+
gesture.onTouchesUp?.(event, manager);
|
|
78
|
+
else if (type === TOUCH_EVENT.CANCELLED)
|
|
79
|
+
gesture.onTouchesCancelled?.(event, manager);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Build the worklet that receives a view's gesture events.
|
|
83
|
+
*
|
|
84
|
+
* `createManager` is the library's `GestureStateManager.create`, passed in rather than imported
|
|
85
|
+
* for the reason the constants are restated. It has to be a worklet itself: everything this
|
|
86
|
+
* closure holds is serialised onto the UI runtime with it.
|
|
87
|
+
*/
|
|
88
|
+
export function gestureDispatcher(callbacks, createManager) {
|
|
89
|
+
// Captured, not passed: a worklet's closure is serialised once and reused, so this is how what
|
|
90
|
+
// one event knew survives to the next. Reanimated's own dispatcher keeps its state the same way.
|
|
91
|
+
const memory = { previous: {}, managers: {} };
|
|
92
|
+
return (event) => {
|
|
93
|
+
'worklet';
|
|
94
|
+
for (const gesture of callbacks) {
|
|
95
|
+
if (event.handlerTag !== gesture.handlerTag)
|
|
96
|
+
continue;
|
|
97
|
+
if (event.oldState != null)
|
|
98
|
+
stateChange(gesture, event, memory);
|
|
99
|
+
else if (event.eventType != null)
|
|
100
|
+
touches(gesture, event, memory, createManager);
|
|
101
|
+
else
|
|
102
|
+
update(gesture, event, memory);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=gesture-dispatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gesture-dispatch.js","sourceRoot":"","sources":["../src/gesture-dispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,+CAA+C;AAC/C,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,YAAY,EAAE,CAAC;IACf,MAAM,EAAE,CAAC;IACT,KAAK,EAAE,CAAC;IACR,SAAS,EAAE,CAAC;IACZ,MAAM,EAAE,CAAC;IACT,GAAG,EAAE,CAAC;CACE,CAAC;AAEX,wDAAwD;AACxD,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,YAAY,EAAE,CAAC;IACf,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,EAAE,EAAE,CAAC;IACL,SAAS,EAAE,CAAC;CACJ,CAAC;AAwCX,SAAS,WAAW,CAAC,OAAyB,EAAE,KAAmB,EAAE,MAAc;IACjF,SAAS,CAAC;IACV,MAAM,KAAK,GAAG,KAAK,CAAC,KAAe,CAAC;IACpC,+FAA+F;IAC/F,6FAA6F;IAC7F,uCAAuC;IACvC,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,KAAK,aAAa,CAAC,MAAM,CAAC;IAC1D,IAAI,KAAK,KAAK,aAAa,CAAC,KAAK,EAAE,CAAC;QAClC,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;SAAM,IAAI,KAAK,KAAK,aAAa,CAAC,MAAM,EAAE,CAAC;QAC1C,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;QACzB,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;IAClD,CAAC;SAAM,IACL,KAAK,KAAK,aAAa,CAAC,GAAG;QAC3B,KAAK,KAAK,aAAa,CAAC,MAAM;QAC9B,KAAK,KAAK,aAAa,CAAC,SAAS,EACjC,CAAC;QACD,MAAM,SAAS,GAAG,KAAK,KAAK,aAAa,CAAC,GAAG,CAAC;QAC9C,IAAI,SAAS;YAAE,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QACjD,OAAO,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACzC,CAAC;AACH,CAAC;AAED,SAAS,MAAM,CAAC,OAAyB,EAAE,KAAmB,EAAE,MAAc;IAC5E,SAAS,CAAC;IACV,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC;IAC1B,4FAA4F;IAC5F,+FAA+F;IAC/F,IAAI,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,qBAAqB,EAAE,CAAC;QACtD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,qBAAqB,CAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAC5F,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,KAAK,CAAC;IAC9C,CAAC;AACH,CAAC;AAED,SAAS,OAAO,CACd,OAAyB,EACzB,KAAmB,EACnB,MAAc,EACd,aAA0D;IAE1D,SAAS,CAAC;IACV,IAAI,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAClD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC5C,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC;IAChD,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC;IAC7B,IAAI,IAAI,KAAK,WAAW,CAAC,IAAI;QAAE,OAAO,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;SAClE,IAAI,IAAI,KAAK,WAAW,CAAC,IAAI;QAAE,OAAO,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;SACvE,IAAI,IAAI,KAAK,WAAW,CAAC,EAAE;QAAE,OAAO,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;SACnE,IAAI,IAAI,KAAK,WAAW,CAAC,SAAS;QAAE,OAAO,CAAC,kBAAkB,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AACxF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAC/B,SAAsC,EACtC,aAA0D;IAE1D,+FAA+F;IAC/F,iGAAiG;IACjG,MAAM,MAAM,GAAW,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IACtD,OAAO,CAAC,KAAmB,EAAE,EAAE;QAC7B,SAAS,CAAC;QACV,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE,CAAC;YAChC,IAAI,KAAK,CAAC,UAAU,KAAK,OAAO,CAAC,UAAU;gBAAE,SAAS;YACtD,IAAI,KAAK,CAAC,QAAQ,IAAI,IAAI;gBAAE,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;iBAC3D,IAAI,KAAK,CAAC,SAAS,IAAI,IAAI;gBAAE,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;;gBAC5E,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QACtC,CAAC;IACH,CAAC,CAAC;AACJ,CAAC","sourcesContent":["/**\n * The state machine between a gesture's raw events and the callbacks it declared.\n *\n * This is what `useAnimatedGesture` does with hooks in react-native-gesture-handler, and the only\n * part of a gesture we write rather than borrow. It is here, apart from the library, so it can be\n * driven by a test: on a device it is serialised onto the UI runtime and a mistake in it is a\n * callback that silently never runs.\n *\n * The numbers below are the ones on the wire. They are the library's `State` and `TouchEventType`,\n * restated rather than imported because importing them would reach React Native's Flow source and\n * make this package unloadable in Node - and because they are a protocol between native and us,\n * not an API surface: native puts these integers in the event.\n */\n\n/** `State` in react-native-gesture-handler. */\nexport const GESTURE_STATE = {\n UNDETERMINED: 0,\n FAILED: 1,\n BEGAN: 2,\n CANCELLED: 3,\n ACTIVE: 4,\n END: 5,\n} as const;\n\n/** `TouchEventType` in react-native-gesture-handler. */\nexport const TOUCH_EVENT = {\n UNDETERMINED: 0,\n DOWN: 1,\n MOVE: 2,\n UP: 3,\n CANCELLED: 4,\n} as const;\n\n/** Lets a touch callback accept or reject the gesture from the UI thread. */\nexport interface GestureStateManager {\n begin(): void;\n activate(): void;\n fail(): void;\n end(): void;\n}\n\n/** A gesture's declared callbacks, as the library leaves them once it has prepared the gesture. */\nexport interface GestureCallbacks {\n handlerTag: number;\n onBegin?: (event: object) => void;\n onStart?: (event: object) => void;\n onUpdate?: (event: object) => void;\n onChange?: (event: object) => void;\n onEnd?: (event: object, success: boolean) => void;\n onFinalize?: (event: object, success: boolean) => void;\n onTouchesDown?: (event: object, manager: GestureStateManager) => void;\n onTouchesMove?: (event: object, manager: GestureStateManager) => void;\n onTouchesUp?: (event: object, manager: GestureStateManager) => void;\n onTouchesCancelled?: (event: object, manager: GestureStateManager) => void;\n changeEventCalculator?: (current: object, previous?: object) => object;\n}\n\n/** What native sends. Which of the three kinds it is, is told by which fields are present. */\nexport interface GestureEvent {\n handlerTag: number;\n state?: number;\n oldState?: number;\n eventType?: number;\n}\n\n/** Per-gesture memory the dispatcher keeps across events. */\ninterface Memory {\n previous: Record<number, object | undefined>;\n managers: Record<number, GestureStateManager | undefined>;\n}\n\nfunction stateChange(gesture: GestureCallbacks, event: GestureEvent, memory: Memory): void {\n 'worklet';\n const state = event.state as number;\n // A state-change event is a transition, so `oldState !== state` always holds and the only part\n // of the old state that matters is whether the gesture had gone active: that is what decides\n // between an end and a finalize alone.\n const wasActive = event.oldState === GESTURE_STATE.ACTIVE;\n if (state === GESTURE_STATE.BEGAN) {\n gesture.onBegin?.(event);\n } else if (state === GESTURE_STATE.ACTIVE) {\n gesture.onStart?.(event);\n memory.previous[gesture.handlerTag] = undefined;\n } else if (\n state === GESTURE_STATE.END ||\n state === GESTURE_STATE.FAILED ||\n state === GESTURE_STATE.CANCELLED\n ) {\n const succeeded = state === GESTURE_STATE.END;\n if (wasActive) gesture.onEnd?.(event, succeeded);\n gesture.onFinalize?.(event, succeeded);\n }\n}\n\nfunction update(gesture: GestureCallbacks, event: GestureEvent, memory: Memory): void {\n 'worklet';\n gesture.onUpdate?.(event);\n // `onChange` is `onUpdate` measured against the event before it, which is what makes a drag\n // accumulate rather than jump. The calculator belongs to the gesture; only the memory is ours.\n if (gesture.onChange && gesture.changeEventCalculator) {\n gesture.onChange(gesture.changeEventCalculator(event, memory.previous[gesture.handlerTag]));\n memory.previous[gesture.handlerTag] = event;\n }\n}\n\nfunction touches(\n gesture: GestureCallbacks,\n event: GestureEvent,\n memory: Memory,\n createManager: (handlerTag: number) => GestureStateManager,\n): void {\n 'worklet';\n let manager = memory.managers[gesture.handlerTag];\n if (!manager) {\n manager = createManager(gesture.handlerTag);\n memory.managers[gesture.handlerTag] = manager;\n }\n const type = event.eventType;\n if (type === TOUCH_EVENT.DOWN) gesture.onTouchesDown?.(event, manager);\n else if (type === TOUCH_EVENT.MOVE) gesture.onTouchesMove?.(event, manager);\n else if (type === TOUCH_EVENT.UP) gesture.onTouchesUp?.(event, manager);\n else if (type === TOUCH_EVENT.CANCELLED) gesture.onTouchesCancelled?.(event, manager);\n}\n\n/**\n * Build the worklet that receives a view's gesture events.\n *\n * `createManager` is the library's `GestureStateManager.create`, passed in rather than imported\n * for the reason the constants are restated. It has to be a worklet itself: everything this\n * closure holds is serialised onto the UI runtime with it.\n */\nexport function gestureDispatcher(\n callbacks: readonly GestureCallbacks[],\n createManager: (handlerTag: number) => GestureStateManager,\n): (event: GestureEvent) => void {\n // Captured, not passed: a worklet's closure is serialised once and reused, so this is how what\n // one event knew survives to the next. Reanimated's own dispatcher keeps its state the same way.\n const memory: Memory = { previous: {}, managers: {} };\n return (event: GestureEvent) => {\n 'worklet';\n for (const gesture of callbacks) {\n if (event.handlerTag !== gesture.handlerTag) continue;\n if (event.oldState != null) stateChange(gesture, event, memory);\n else if (event.eventType != null) touches(gesture, event, memory, createManager);\n else update(gesture, event, memory);\n }\n };\n}\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import 'react-native-gesture-handler';
|
|
2
|
+
import { NativeGestureBase } from './native-gesture.ts';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export { type GestureSpec, type GestureTarget } from './gesture-backend.ts';
|
|
5
|
+
export declare class NativeGesture extends NativeGestureBase {
|
|
6
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NativeGesture, never>;
|
|
7
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<NativeGesture, "[gesture]", never, {}, {}, never, never, true, never>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The root the gestures are recognised inside. Wrap the app in one, as the library's own
|
|
11
|
+
* `GestureHandlerRootView` is wrapped.
|
|
12
|
+
*
|
|
13
|
+
* **It is a different view on each platform, and that is the library's own split.**
|
|
14
|
+
* `RNGestureHandlerRootView` is an Android view group that intercepts touches before the rest of
|
|
15
|
+
* the tree sees them; on iOS the recognisers hang off the target view itself, the component
|
|
16
|
+
* provider returns nil, and their own root view renders a plain `View`. Registering the native
|
|
17
|
+
* name on both would render an unimplemented component on iOS.
|
|
18
|
+
*/
|
|
19
|
+
export declare class GestureRoot {
|
|
20
|
+
constructor();
|
|
21
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<GestureRoot, never>;
|
|
22
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<GestureRoot, "gesture-root", never, {}, {}, never, ["*"], true, never>;
|
|
23
|
+
}
|
package/dist/gestures.js
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* react-native-gesture-handler, without React: a native gesture attached to one of our nodes.
|
|
3
|
+
*
|
|
4
|
+
* ```ts
|
|
5
|
+
* import { Gesture } from 'react-native-gesture-handler';
|
|
6
|
+
* import { NativeGesture } from '@ng-native/components/gestures';
|
|
7
|
+
*
|
|
8
|
+
* protected readonly pan = Gesture.Pan().onUpdate((event) => {
|
|
9
|
+
* 'worklet';
|
|
10
|
+
* x.value = event.translationX;
|
|
11
|
+
* });
|
|
12
|
+
* ```
|
|
13
|
+
* ```html
|
|
14
|
+
* <gesture-root>
|
|
15
|
+
* <view [gesture]="pan" [workletStyle]="slide"></view>
|
|
16
|
+
* </gesture-root>
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* `GestureDetector` is a React component whose job is to hold a ref, turn it into a view tag, and
|
|
20
|
+
* hand that tag to the native module. Everything under it is a plain function of that tag:
|
|
21
|
+
* `attachHandlers` and `dropHandlers` import no React at runtime, so they are used here as they
|
|
22
|
+
* are, and the gesture objects themselves - `Gesture.Pan()`, the compositions, the config - are
|
|
23
|
+
* the library's own public API and come across untouched.
|
|
24
|
+
*
|
|
25
|
+
* What is written out is the part `useAnimatedGesture` does with hooks: a worklet that turns the
|
|
26
|
+
* raw stream of events into the callbacks a gesture declares. Reanimated's `registerEventHandler`
|
|
27
|
+
* is the same call their `WorkletEventHandler` makes, once per event name per view tag.
|
|
28
|
+
*
|
|
29
|
+
* A gesture whose callbacks are not worklets needs none of that: the library attaches it as a
|
|
30
|
+
* JavaScript-function gesture and its own event receiver, started when the package is first
|
|
31
|
+
* imported, calls them on the JavaScript thread.
|
|
32
|
+
*
|
|
33
|
+
* **A gesture callback must not read `this`, on either thread.** The Babel plugin rewrites one
|
|
34
|
+
* into a worklet whether or not it will run on the UI thread, and a rewritten callback has no
|
|
35
|
+
* `this`; `runOnJS(true)` decides where it runs, not what it may close over. Read what it needs
|
|
36
|
+
* through a local, as a worklet style does.
|
|
37
|
+
*
|
|
38
|
+
* **The internals are reached through `src/`, and that is load-bearing.** Both libraries point
|
|
39
|
+
* their `react-native` package field at their TypeScript source, and Metro prefers that field, so
|
|
40
|
+
* `react-native-gesture-handler` in an app resolves to `src/index.ts`. Importing the built `lib/`
|
|
41
|
+
* copy of a file instead gives a second, parallel copy of the library with its own module state:
|
|
42
|
+
* handlers registered in one copy's registry, the event receiver listening in the other's, and
|
|
43
|
+
* every JavaScript gesture silently doing nothing.
|
|
44
|
+
*
|
|
45
|
+
* Deliberately outside the barrel: everything here reaches React Native's Flow source, which Node
|
|
46
|
+
* cannot parse, and the rest of the package has to stay loadable in the test suite.
|
|
47
|
+
*/
|
|
48
|
+
import { Component, Directive, ElementRef, inject } from '@angular/core';
|
|
49
|
+
// For the side effect: evaluating the package's index is what starts its event receiver, which
|
|
50
|
+
// is what delivers a gesture whose callbacks are ordinary functions. An app importing `Gesture`
|
|
51
|
+
// does this too; this file does not depend on that.
|
|
52
|
+
import 'react-native-gesture-handler';
|
|
53
|
+
import { claimHost, nativePlatform, registerViewName } from '@ng-native/fabric';
|
|
54
|
+
import { gestureDispatcher, } from "./gesture-dispatch.js";
|
|
55
|
+
import { GESTURES } from "./gesture-backend.js";
|
|
56
|
+
import { NativeGestureBase } from "./native-gesture.js";
|
|
57
|
+
import * as i0 from "@angular/core";
|
|
58
|
+
export {} from "./gesture-backend.js";
|
|
59
|
+
/**
|
|
60
|
+
* The internals, required rather than imported, and each with a literal path because Metro builds
|
|
61
|
+
* its graph from those.
|
|
62
|
+
*
|
|
63
|
+
* Not for laziness: a static import would put these TypeScript sources into our own type-checking
|
|
64
|
+
* program, where they fail against settings of ours they were never written for
|
|
65
|
+
* (`verbatimModuleSyntax`, `erasableSyntaxOnly`). `require` asks Metro for the module and leaves
|
|
66
|
+
* the compiler out of it, which is the same trade `@ng-native/device` makes for React Native.
|
|
67
|
+
*/
|
|
68
|
+
const { attachHandlers } = require('react-native-gesture-handler/src/handlers/gestures/GestureDetector/attachHandlers.ts');
|
|
69
|
+
const { dropHandlers } = require('react-native-gesture-handler/src/handlers/gestures/GestureDetector/dropHandlers.ts');
|
|
70
|
+
const { maybeInitializeFabric } = require('react-native-gesture-handler/src/init.ts');
|
|
71
|
+
const { GestureStateManager } = require('react-native-gesture-handler/src/handlers/gestures/gestureStateManager.ts');
|
|
72
|
+
/**
|
|
73
|
+
* The same call Reanimated's own `WorkletEventHandler` makes: one registration per event name per
|
|
74
|
+
* view tag, which is all a gesture needs to reach the UI runtime. Not public either.
|
|
75
|
+
*/
|
|
76
|
+
const { registerEventHandler, unregisterEventHandler } = require('react-native-reanimated/src/core.ts');
|
|
77
|
+
const EVENT_NAMES = ['onGestureHandlerStateChange', 'onGestureHandlerEvent'];
|
|
78
|
+
/**
|
|
79
|
+
* A gesture's own state controller, for the touch callbacks: a worklet that accepts or rejects
|
|
80
|
+
* the gesture while it is still being recognised. Wrapped in a worklet of ours because everything
|
|
81
|
+
* the dispatcher closes over is serialised onto the UI runtime with it.
|
|
82
|
+
*/
|
|
83
|
+
const createManager = (handlerTag) => {
|
|
84
|
+
'worklet';
|
|
85
|
+
return GestureStateManager.create(handlerTag);
|
|
86
|
+
};
|
|
87
|
+
const backend = {
|
|
88
|
+
attach: (target, gesture) => {
|
|
89
|
+
maybeInitializeFabric();
|
|
90
|
+
const config = gesture;
|
|
91
|
+
const gesturesToAttach = config.toGestureArray();
|
|
92
|
+
// The library's own state object. Only `isMounted` is read back by anything of ours - the
|
|
93
|
+
// microtasks `attachHandlers` queues check it, so a directive torn down in the same tick as
|
|
94
|
+
// it was created does not attach a handler nobody will drop.
|
|
95
|
+
const prepared = {
|
|
96
|
+
attachedGestures: [],
|
|
97
|
+
animatedEventHandler: null,
|
|
98
|
+
animatedHandlers: null,
|
|
99
|
+
shouldUseReanimated: gesturesToAttach.some((g) => g.shouldUseReanimated),
|
|
100
|
+
isMounted: true,
|
|
101
|
+
};
|
|
102
|
+
attachHandlers({
|
|
103
|
+
preparedGesture: prepared,
|
|
104
|
+
gestureConfig: config,
|
|
105
|
+
gesturesToAttach,
|
|
106
|
+
viewTag: target.tag,
|
|
107
|
+
// Web only, and there is no web here. The library reads `.current` off it on that platform.
|
|
108
|
+
webEventHandlersRef: { current: {} },
|
|
109
|
+
});
|
|
110
|
+
// One dispatcher for both event names, as the library's own event handler is: a gesture's
|
|
111
|
+
// state changes and its updates arrive on different names and share the same state.
|
|
112
|
+
const animated = gesturesToAttach.filter((g) => g.shouldUseReanimated);
|
|
113
|
+
const dispatch = gestureDispatcher(animated.map((g) => g.handlers), createManager);
|
|
114
|
+
const registrations = animated.length
|
|
115
|
+
? EVENT_NAMES.map((name) => registerEventHandler(dispatch, name, target.tag))
|
|
116
|
+
: [];
|
|
117
|
+
return () => {
|
|
118
|
+
prepared.isMounted = false;
|
|
119
|
+
for (const id of registrations)
|
|
120
|
+
unregisterEventHandler(id);
|
|
121
|
+
dropHandlers(prepared);
|
|
122
|
+
};
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
export class NativeGesture extends NativeGestureBase {
|
|
126
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: NativeGesture, deps: null, target: i0.ɵɵFactoryTarget.Directive });
|
|
127
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.2.0", type: NativeGesture, isStandalone: true, selector: "[gesture]", providers: [{ provide: GESTURES, useValue: backend }], usesInheritance: true, ngImport: i0 });
|
|
128
|
+
}
|
|
129
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: NativeGesture, decorators: [{
|
|
130
|
+
type: Directive,
|
|
131
|
+
args: [{
|
|
132
|
+
selector: '[gesture]',
|
|
133
|
+
providers: [{ provide: GESTURES, useValue: backend }],
|
|
134
|
+
}]
|
|
135
|
+
}] });
|
|
136
|
+
/**
|
|
137
|
+
* The root the gestures are recognised inside. Wrap the app in one, as the library's own
|
|
138
|
+
* `GestureHandlerRootView` is wrapped.
|
|
139
|
+
*
|
|
140
|
+
* **It is a different view on each platform, and that is the library's own split.**
|
|
141
|
+
* `RNGestureHandlerRootView` is an Android view group that intercepts touches before the rest of
|
|
142
|
+
* the tree sees them; on iOS the recognisers hang off the target view itself, the component
|
|
143
|
+
* provider returns nil, and their own root view renders a plain `View`. Registering the native
|
|
144
|
+
* name on both would render an unimplemented component on iOS.
|
|
145
|
+
*/
|
|
146
|
+
export class GestureRoot {
|
|
147
|
+
constructor() {
|
|
148
|
+
const android = nativePlatform() === 'android';
|
|
149
|
+
registerViewName('gesture-root', android ? 'RNGestureHandlerRootView' : 'RCTView', {
|
|
150
|
+
flex: 1,
|
|
151
|
+
});
|
|
152
|
+
claimHost(inject(ElementRef).nativeElement);
|
|
153
|
+
// The library does this in its root view's render: it installs the JSI bindings the new
|
|
154
|
+
// architecture needs, and it can only happen once Fabric is there to install them into.
|
|
155
|
+
maybeInitializeFabric();
|
|
156
|
+
}
|
|
157
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: GestureRoot, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
158
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.2.0", type: GestureRoot, isStandalone: true, selector: "gesture-root", ngImport: i0, template: '<ng-content />', isInline: true });
|
|
159
|
+
}
|
|
160
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: GestureRoot, decorators: [{
|
|
161
|
+
type: Component,
|
|
162
|
+
args: [{ selector: 'gesture-root', template: '<ng-content />' }]
|
|
163
|
+
}], ctorParameters: () => [] });
|
|
164
|
+
//# sourceMappingURL=gestures.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gestures.js","sourceRoot":"","sources":["../src/gestures.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * react-native-gesture-handler, without React: a native gesture attached to one of our nodes.\n *\n * ```ts\n * import { Gesture } from 'react-native-gesture-handler';\n * import { NativeGesture } from '@ng-native/components/gestures';\n *\n * protected readonly pan = Gesture.Pan().onUpdate((event) => {\n * 'worklet';\n * x.value = event.translationX;\n * });\n * ```\n * ```html\n * <gesture-root>\n * <view [gesture]=\"pan\" [workletStyle]=\"slide\"></view>\n * </gesture-root>\n * ```\n *\n * `GestureDetector` is a React component whose job is to hold a ref, turn it into a view tag, and\n * hand that tag to the native module. Everything under it is a plain function of that tag:\n * `attachHandlers` and `dropHandlers` import no React at runtime, so they are used here as they\n * are, and the gesture objects themselves - `Gesture.Pan()`, the compositions, the config - are\n * the library's own public API and come across untouched.\n *\n * What is written out is the part `useAnimatedGesture` does with hooks: a worklet that turns the\n * raw stream of events into the callbacks a gesture declares. Reanimated's `registerEventHandler`\n * is the same call their `WorkletEventHandler` makes, once per event name per view tag.\n *\n * A gesture whose callbacks are not worklets needs none of that: the library attaches it as a\n * JavaScript-function gesture and its own event receiver, started when the package is first\n * imported, calls them on the JavaScript thread.\n *\n * **A gesture callback must not read `this`, on either thread.** The Babel plugin rewrites one\n * into a worklet whether or not it will run on the UI thread, and a rewritten callback has no\n * `this`; `runOnJS(true)` decides where it runs, not what it may close over. Read what it needs\n * through a local, as a worklet style does.\n *\n * **The internals are reached through `src/`, and that is load-bearing.** Both libraries point\n * their `react-native` package field at their TypeScript source, and Metro prefers that field, so\n * `react-native-gesture-handler` in an app resolves to `src/index.ts`. Importing the built `lib/`\n * copy of a file instead gives a second, parallel copy of the library with its own module state:\n * handlers registered in one copy's registry, the event receiver listening in the other's, and\n * every JavaScript gesture silently doing nothing.\n *\n * Deliberately outside the barrel: everything here reaches React Native's Flow source, which Node\n * cannot parse, and the rest of the package has to stay loadable in the test suite.\n */\nimport { Component, Directive, ElementRef, inject } from '@angular/core';\n// For the side effect: evaluating the package's index is what starts its event receiver, which\n// is what delivers a gesture whose callbacks are ordinary functions. An app importing `Gesture`\n// does this too; this file does not depend on that.\nimport 'react-native-gesture-handler';\nimport { claimHost, nativePlatform, registerViewName, type HostNode } from '@ng-native/fabric';\nimport {\n gestureDispatcher,\n type GestureCallbacks,\n type GestureStateManager,\n} from './gesture-dispatch.ts';\nimport { GESTURES, type GestureBackend } from './gesture-backend.ts';\nimport { NativeGestureBase } from './native-gesture.ts';\n\nexport { type GestureSpec, type GestureTarget } from './gesture-backend.ts';\n\n/**\n * The internals, required rather than imported, and each with a literal path because Metro builds\n * its graph from those.\n *\n * Not for laziness: a static import would put these TypeScript sources into our own type-checking\n * program, where they fail against settings of ours they were never written for\n * (`verbatimModuleSyntax`, `erasableSyntaxOnly`). `require` asks Metro for the module and leaves\n * the compiler out of it, which is the same trade `@ng-native/device` makes for React Native.\n */\nconst { attachHandlers } =\n require('react-native-gesture-handler/src/handlers/gestures/GestureDetector/attachHandlers.ts') as {\n attachHandlers(config: {\n preparedGesture: object;\n gestureConfig: object;\n gesturesToAttach: readonly object[];\n viewTag: number;\n webEventHandlersRef: object;\n }): void;\n };\n\nconst { dropHandlers } =\n require('react-native-gesture-handler/src/handlers/gestures/GestureDetector/dropHandlers.ts') as {\n dropHandlers(prepared: object): void;\n };\n\nconst { maybeInitializeFabric } = require('react-native-gesture-handler/src/init.ts') as {\n maybeInitializeFabric(): void;\n};\n\nconst { GestureStateManager } =\n require('react-native-gesture-handler/src/handlers/gestures/gestureStateManager.ts') as {\n GestureStateManager: { create(handlerTag: number): GestureStateManager };\n };\n\n/**\n * The same call Reanimated's own `WorkletEventHandler` makes: one registration per event name per\n * view tag, which is all a gesture needs to reach the UI runtime. Not public either.\n */\nconst { registerEventHandler, unregisterEventHandler } =\n require('react-native-reanimated/src/core.ts') as {\n registerEventHandler(\n worklet: (event: never) => void,\n eventName: string,\n emitterReactTag: number,\n ): number;\n unregisterEventHandler(id: number): void;\n };\n\n/** The gesture object, as far as this file needs to know it. */\ninterface Attachable {\n initialize(): void;\n prepare(): void;\n toGestureArray(): { handlers: GestureCallbacks; shouldUseReanimated: boolean }[];\n}\n\nconst EVENT_NAMES = ['onGestureHandlerStateChange', 'onGestureHandlerEvent'];\n\n/**\n * A gesture's own state controller, for the touch callbacks: a worklet that accepts or rejects\n * the gesture while it is still being recognised. Wrapped in a worklet of ours because everything\n * the dispatcher closes over is serialised onto the UI runtime with it.\n */\nconst createManager = (handlerTag: number): GestureStateManager => {\n 'worklet';\n return GestureStateManager.create(handlerTag);\n};\n\nconst backend: GestureBackend = {\n attach: (target, gesture) => {\n maybeInitializeFabric();\n const config = gesture as Attachable;\n const gesturesToAttach = config.toGestureArray();\n // The library's own state object. Only `isMounted` is read back by anything of ours - the\n // microtasks `attachHandlers` queues check it, so a directive torn down in the same tick as\n // it was created does not attach a handler nobody will drop.\n const prepared = {\n attachedGestures: [],\n animatedEventHandler: null,\n animatedHandlers: null,\n shouldUseReanimated: gesturesToAttach.some((g) => g.shouldUseReanimated),\n isMounted: true,\n };\n attachHandlers({\n preparedGesture: prepared,\n gestureConfig: config,\n gesturesToAttach,\n viewTag: target.tag,\n // Web only, and there is no web here. The library reads `.current` off it on that platform.\n webEventHandlersRef: { current: {} },\n });\n\n // One dispatcher for both event names, as the library's own event handler is: a gesture's\n // state changes and its updates arrive on different names and share the same state.\n const animated = gesturesToAttach.filter((g) => g.shouldUseReanimated);\n const dispatch = gestureDispatcher(\n animated.map((g) => g.handlers),\n createManager,\n );\n const registrations = animated.length\n ? EVENT_NAMES.map((name) => registerEventHandler(dispatch, name, target.tag))\n : [];\n\n return () => {\n prepared.isMounted = false;\n for (const id of registrations) unregisterEventHandler(id);\n dropHandlers(prepared);\n };\n },\n};\n\n@Directive({\n selector: '[gesture]',\n providers: [{ provide: GESTURES, useValue: backend }],\n})\nexport class NativeGesture extends NativeGestureBase {}\n\n/**\n * The root the gestures are recognised inside. Wrap the app in one, as the library's own\n * `GestureHandlerRootView` is wrapped.\n *\n * **It is a different view on each platform, and that is the library's own split.**\n * `RNGestureHandlerRootView` is an Android view group that intercepts touches before the rest of\n * the tree sees them; on iOS the recognisers hang off the target view itself, the component\n * provider returns nil, and their own root view renders a plain `View`. Registering the native\n * name on both would render an unimplemented component on iOS.\n */\n@Component({ selector: 'gesture-root', template: '<ng-content />' })\nexport class GestureRoot {\n constructor() {\n const android = nativePlatform() === 'android';\n registerViewName('gesture-root', android ? 'RNGestureHandlerRootView' : 'RCTView', {\n flex: 1,\n });\n claimHost(inject(ElementRef).nativeElement as HostNode);\n // The library does this in its root view's render: it installs the JSI bindings the new\n // architecture needs, and it can only happen once Fabric is there to install them into.\n maybeInitializeFabric();\n }\n}\n"]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Row sizes and the offsets they add up to, as a Fenwick tree: changing one row's size, finding
|
|
3
|
+
* where a row starts and finding the row at a point each cost a walk of about log2(n) steps.
|
|
4
|
+
*
|
|
5
|
+
* A list of rows that size themselves learns heights one row at a time as rows lay out, and a
|
|
6
|
+
* fling through rows it has not seen yet measures a few every frame. Rebuilding a plain table of
|
|
7
|
+
* offsets for each of those is a walk over every row, which at ten thousand rows is most of a
|
|
8
|
+
* frame on a phone. This keeps that cost to building the index once per change of items.
|
|
9
|
+
*/
|
|
10
|
+
export declare class HeightIndex {
|
|
11
|
+
/** Each row's size, for `heightOf` without a query. */
|
|
12
|
+
private readonly sizes;
|
|
13
|
+
/** The tree, one-based: `tree[i]` sums the `i & -i` sizes ending at row `i - 1`. */
|
|
14
|
+
private readonly tree;
|
|
15
|
+
/** The highest power of two within the row count, where a descent starts. */
|
|
16
|
+
private readonly top;
|
|
17
|
+
constructor(sizes: ArrayLike<number>);
|
|
18
|
+
get length(): number;
|
|
19
|
+
/** The sum of every row's size. */
|
|
20
|
+
get total(): number;
|
|
21
|
+
heightOf(index: number): number;
|
|
22
|
+
/** Where row `index` starts: the sum of the sizes before it. Past the end, the total. */
|
|
23
|
+
topOf(index: number): number;
|
|
24
|
+
/** Change one row's size, and with it where every later row starts. */
|
|
25
|
+
set(index: number, size: number): void;
|
|
26
|
+
/**
|
|
27
|
+
* The row that `y` falls in: the last row starting at or before it, clamped to the rows there
|
|
28
|
+
* are. A descent through the tree rather than a binary search over `topOf`, so one walk.
|
|
29
|
+
*/
|
|
30
|
+
indexAt(y: number): number;
|
|
31
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Row sizes and the offsets they add up to, as a Fenwick tree: changing one row's size, finding
|
|
3
|
+
* where a row starts and finding the row at a point each cost a walk of about log2(n) steps.
|
|
4
|
+
*
|
|
5
|
+
* A list of rows that size themselves learns heights one row at a time as rows lay out, and a
|
|
6
|
+
* fling through rows it has not seen yet measures a few every frame. Rebuilding a plain table of
|
|
7
|
+
* offsets for each of those is a walk over every row, which at ten thousand rows is most of a
|
|
8
|
+
* frame on a phone. This keeps that cost to building the index once per change of items.
|
|
9
|
+
*/
|
|
10
|
+
export class HeightIndex {
|
|
11
|
+
/** Each row's size, for `heightOf` without a query. */
|
|
12
|
+
sizes;
|
|
13
|
+
/** The tree, one-based: `tree[i]` sums the `i & -i` sizes ending at row `i - 1`. */
|
|
14
|
+
tree;
|
|
15
|
+
/** The highest power of two within the row count, where a descent starts. */
|
|
16
|
+
top;
|
|
17
|
+
constructor(sizes) {
|
|
18
|
+
const count = sizes.length;
|
|
19
|
+
this.sizes = Float64Array.from(sizes);
|
|
20
|
+
this.tree = new Float64Array(count + 1);
|
|
21
|
+
// Linear construction: each node passes its sum to its parent once.
|
|
22
|
+
for (let i = 1; i <= count; i++) {
|
|
23
|
+
this.tree[i] += this.sizes[i - 1];
|
|
24
|
+
const parent = i + (i & -i);
|
|
25
|
+
if (parent <= count)
|
|
26
|
+
this.tree[parent] += this.tree[i];
|
|
27
|
+
}
|
|
28
|
+
let top = 1;
|
|
29
|
+
while (top * 2 <= count)
|
|
30
|
+
top *= 2;
|
|
31
|
+
this.top = count ? top : 0;
|
|
32
|
+
}
|
|
33
|
+
get length() {
|
|
34
|
+
return this.sizes.length;
|
|
35
|
+
}
|
|
36
|
+
/** The sum of every row's size. */
|
|
37
|
+
get total() {
|
|
38
|
+
return this.topOf(this.sizes.length);
|
|
39
|
+
}
|
|
40
|
+
heightOf(index) {
|
|
41
|
+
return this.sizes[index] ?? 0;
|
|
42
|
+
}
|
|
43
|
+
/** Where row `index` starts: the sum of the sizes before it. Past the end, the total. */
|
|
44
|
+
topOf(index) {
|
|
45
|
+
let sum = 0;
|
|
46
|
+
for (let i = Math.min(index, this.sizes.length); i > 0; i -= i & -i)
|
|
47
|
+
sum += this.tree[i];
|
|
48
|
+
return sum;
|
|
49
|
+
}
|
|
50
|
+
/** Change one row's size, and with it where every later row starts. */
|
|
51
|
+
set(index, size) {
|
|
52
|
+
const delta = size - this.sizes[index];
|
|
53
|
+
if (delta === 0)
|
|
54
|
+
return;
|
|
55
|
+
this.sizes[index] = size;
|
|
56
|
+
for (let i = index + 1; i <= this.sizes.length; i += i & -i)
|
|
57
|
+
this.tree[i] += delta;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The row that `y` falls in: the last row starting at or before it, clamped to the rows there
|
|
61
|
+
* are. A descent through the tree rather than a binary search over `topOf`, so one walk.
|
|
62
|
+
*/
|
|
63
|
+
indexAt(y) {
|
|
64
|
+
const count = this.sizes.length;
|
|
65
|
+
if (count === 0)
|
|
66
|
+
return 0;
|
|
67
|
+
let position = 0;
|
|
68
|
+
let remaining = y;
|
|
69
|
+
for (let step = this.top; step > 0; step >>= 1) {
|
|
70
|
+
const next = position + step;
|
|
71
|
+
if (next <= count && this.tree[next] <= remaining) {
|
|
72
|
+
position = next;
|
|
73
|
+
remaining -= this.tree[next];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// `position` rows end at or before `y`, so `y` is in the next one.
|
|
77
|
+
return Math.min(position, count - 1);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=height-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"height-index.js","sourceRoot":"","sources":["../src/height-index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Row sizes and the offsets they add up to, as a Fenwick tree: changing one row's size, finding\n * where a row starts and finding the row at a point each cost a walk of about log2(n) steps.\n *\n * A list of rows that size themselves learns heights one row at a time as rows lay out, and a\n * fling through rows it has not seen yet measures a few every frame. Rebuilding a plain table of\n * offsets for each of those is a walk over every row, which at ten thousand rows is most of a\n * frame on a phone. This keeps that cost to building the index once per change of items.\n */\nexport class HeightIndex {\n /** Each row's size, for `heightOf` without a query. */\n private readonly sizes: Float64Array;\n /** The tree, one-based: `tree[i]` sums the `i & -i` sizes ending at row `i - 1`. */\n private readonly tree: Float64Array;\n /** The highest power of two within the row count, where a descent starts. */\n private readonly top: number;\n\n constructor(sizes: ArrayLike<number>) {\n const count = sizes.length;\n this.sizes = Float64Array.from(sizes);\n this.tree = new Float64Array(count + 1);\n // Linear construction: each node passes its sum to its parent once.\n for (let i = 1; i <= count; i++) {\n this.tree[i]! += this.sizes[i - 1]!;\n const parent = i + (i & -i);\n if (parent <= count) this.tree[parent]! += this.tree[i]!;\n }\n let top = 1;\n while (top * 2 <= count) top *= 2;\n this.top = count ? top : 0;\n }\n\n get length(): number {\n return this.sizes.length;\n }\n\n /** The sum of every row's size. */\n get total(): number {\n return this.topOf(this.sizes.length);\n }\n\n heightOf(index: number): number {\n return this.sizes[index] ?? 0;\n }\n\n /** Where row `index` starts: the sum of the sizes before it. Past the end, the total. */\n topOf(index: number): number {\n let sum = 0;\n for (let i = Math.min(index, this.sizes.length); i > 0; i -= i & -i) sum += this.tree[i]!;\n return sum;\n }\n\n /** Change one row's size, and with it where every later row starts. */\n set(index: number, size: number): void {\n const delta = size - this.sizes[index]!;\n if (delta === 0) return;\n this.sizes[index] = size;\n for (let i = index + 1; i <= this.sizes.length; i += i & -i) this.tree[i]! += delta;\n }\n\n /**\n * The row that `y` falls in: the last row starting at or before it, clamped to the rows there\n * are. A descent through the tree rather than a binary search over `topOf`, so one walk.\n */\n indexAt(y: number): number {\n const count = this.sizes.length;\n if (count === 0) return 0;\n let position = 0;\n let remaining = y;\n for (let step = this.top; step > 0; step >>= 1) {\n const next = position + step;\n if (next <= count && this.tree[next]! <= remaining) {\n position = next;\n remaining -= this.tree[next]!;\n }\n }\n // `position` rows end at or before `y`, so `y` is in the next one.\n return Math.min(position, count - 1);\n }\n}\n"]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type ImageResizeMode, type ImageSource } from './image.ts';
|
|
2
|
+
import { ViewBase } from './view-base.ts';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* A view with an image behind its children. RN's `ImageBackground` is a `View` wrapping an
|
|
6
|
+
* absolutely-filled `Image`; there is no native component for it.
|
|
7
|
+
*
|
|
8
|
+
* `imageStyle` styles the image itself. RN also copies the outer style's width and height onto
|
|
9
|
+
* the image, a documented workaround for the image otherwise sizing itself; that is done here
|
|
10
|
+
* from `[style]`, and a background with no size there fills its box at 100%.
|
|
11
|
+
*/
|
|
12
|
+
export declare class ImageBackground extends ViewBase {
|
|
13
|
+
readonly source: import("@angular/core").InputSignal<ImageSource | undefined>;
|
|
14
|
+
readonly defaultSource: import("@angular/core").InputSignal<ImageSource | undefined>;
|
|
15
|
+
readonly resizeMode: import("@angular/core").InputSignal<ImageResizeMode>;
|
|
16
|
+
readonly blurRadius: import("@angular/core").InputSignal<number | undefined>;
|
|
17
|
+
readonly tintColor: import("@angular/core").InputSignal<string | undefined>;
|
|
18
|
+
readonly alt: import("@angular/core").InputSignal<string | undefined>;
|
|
19
|
+
/** Styles applied to the image rather than the container. */
|
|
20
|
+
readonly imageStyle: import("@angular/core").InputSignal<Record<string, unknown> | undefined>;
|
|
21
|
+
protected readonly fill: import("@angular/core").Signal<{
|
|
22
|
+
position: string;
|
|
23
|
+
top: number;
|
|
24
|
+
left: number;
|
|
25
|
+
bottom: number;
|
|
26
|
+
right: number;
|
|
27
|
+
width: {};
|
|
28
|
+
height: {};
|
|
29
|
+
}>;
|
|
30
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ImageBackground, never>;
|
|
31
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ImageBackground, "image-background", never, { "source": { "alias": "source"; "required": false; "isSignal": true; }; "defaultSource": { "alias": "defaultSource"; "required": false; "isSignal": true; }; "resizeMode": { "alias": "resizeMode"; "required": false; "isSignal": true; }; "blurRadius": { "alias": "blurRadius"; "required": false; "isSignal": true; }; "tintColor": { "alias": "tintColor"; "required": false; "isSignal": true; }; "alt": { "alias": "alt"; "required": false; "isSignal": true; }; "imageStyle": { "alias": "imageStyle"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
32
|
+
}
|