@hanzogui/react-native-use-responder-events 2.0.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.
Files changed (74) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cjs/ResponderSystem.cjs +251 -0
  3. package/dist/cjs/ResponderSystem.native.js +253 -0
  4. package/dist/cjs/ResponderSystem.native.js.map +1 -0
  5. package/dist/cjs/ResponderTouchHistoryStore.cjs +112 -0
  6. package/dist/cjs/ResponderTouchHistoryStore.native.js +156 -0
  7. package/dist/cjs/ResponderTouchHistoryStore.native.js.map +1 -0
  8. package/dist/cjs/createResponderEvent.cjs +135 -0
  9. package/dist/cjs/createResponderEvent.native.js +140 -0
  10. package/dist/cjs/createResponderEvent.native.js.map +1 -0
  11. package/dist/cjs/index.cjs +18 -0
  12. package/dist/cjs/index.native.js +21 -0
  13. package/dist/cjs/index.native.js.map +1 -0
  14. package/dist/cjs/types.cjs +76 -0
  15. package/dist/cjs/types.native.js +79 -0
  16. package/dist/cjs/types.native.js.map +1 -0
  17. package/dist/cjs/useResponderEvents.cjs +95 -0
  18. package/dist/cjs/useResponderEvents.native.js +102 -0
  19. package/dist/cjs/useResponderEvents.native.js.map +1 -0
  20. package/dist/cjs/utils.cjs +126 -0
  21. package/dist/cjs/utils.native.js +126 -0
  22. package/dist/cjs/utils.native.js.map +1 -0
  23. package/dist/esm/ResponderSystem.mjs +224 -0
  24. package/dist/esm/ResponderSystem.mjs.map +1 -0
  25. package/dist/esm/ResponderSystem.native.js +223 -0
  26. package/dist/esm/ResponderSystem.native.js.map +1 -0
  27. package/dist/esm/ResponderTouchHistoryStore.mjs +89 -0
  28. package/dist/esm/ResponderTouchHistoryStore.mjs.map +1 -0
  29. package/dist/esm/ResponderTouchHistoryStore.native.js +130 -0
  30. package/dist/esm/ResponderTouchHistoryStore.native.js.map +1 -0
  31. package/dist/esm/createResponderEvent.mjs +112 -0
  32. package/dist/esm/createResponderEvent.mjs.map +1 -0
  33. package/dist/esm/createResponderEvent.native.js +114 -0
  34. package/dist/esm/createResponderEvent.native.js.map +1 -0
  35. package/dist/esm/index.js +2 -0
  36. package/dist/esm/index.js.map +1 -0
  37. package/dist/esm/index.mjs +2 -0
  38. package/dist/esm/index.mjs.map +1 -0
  39. package/dist/esm/index.native.js +2 -0
  40. package/dist/esm/index.native.js.map +1 -0
  41. package/dist/esm/types.mjs +34 -0
  42. package/dist/esm/types.mjs.map +1 -0
  43. package/dist/esm/types.native.js +34 -0
  44. package/dist/esm/types.native.js.map +1 -0
  45. package/dist/esm/useResponderEvents.mjs +59 -0
  46. package/dist/esm/useResponderEvents.mjs.map +1 -0
  47. package/dist/esm/useResponderEvents.native.js +63 -0
  48. package/dist/esm/useResponderEvents.native.js.map +1 -0
  49. package/dist/esm/utils.mjs +95 -0
  50. package/dist/esm/utils.mjs.map +1 -0
  51. package/dist/esm/utils.native.js +92 -0
  52. package/dist/esm/utils.native.js.map +1 -0
  53. package/package.json +42 -0
  54. package/src/ResponderSystem.ts +555 -0
  55. package/src/ResponderTouchHistoryStore.ts +211 -0
  56. package/src/createResponderEvent.ts +190 -0
  57. package/src/index.ts +1 -0
  58. package/src/types.ts +78 -0
  59. package/src/useResponderEvents.ts +107 -0
  60. package/src/utils.ts +196 -0
  61. package/types/ResponderSystem.d.ts +47 -0
  62. package/types/ResponderSystem.d.ts.map +1 -0
  63. package/types/ResponderTouchHistoryStore.d.ts +37 -0
  64. package/types/ResponderTouchHistoryStore.d.ts.map +1 -0
  65. package/types/createResponderEvent.d.ts +36 -0
  66. package/types/createResponderEvent.d.ts.map +1 -0
  67. package/types/index.d.ts +2 -0
  68. package/types/index.d.ts.map +1 -0
  69. package/types/types.d.ts +52 -0
  70. package/types/types.d.ts.map +1 -0
  71. package/types/useResponderEvents.d.ts +10 -0
  72. package/types/useResponderEvents.d.ts.map +1 -0
  73. package/types/utils.d.ts +38 -0
  74. package/types/utils.d.ts.map +1 -0
@@ -0,0 +1,211 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import type { Touch, TouchEvent } from './types'
9
+ import { isEndish, isMoveish, isStartish } from './types'
10
+
11
+ export class ResponderTouchHistoryStore {
12
+ _touchHistory = {
13
+ touchBank: [], //Array<TouchRecord>
14
+ numberActiveTouches: 0,
15
+ // If there is only one active touch, we remember its location. This prevents
16
+ // us having to loop through all of the touches all the time in the most
17
+ // common case.
18
+ indexOfSingleActiveTouch: -1,
19
+ mostRecentTimeStamp: 0,
20
+ }
21
+
22
+ recordTouchTrack(topLevelType: string, nativeEvent: TouchEvent): void {
23
+ const touchHistory = this._touchHistory
24
+ if (isMoveish(topLevelType)) {
25
+ nativeEvent.changedTouches.forEach((touch) => recordTouchMove(touch, touchHistory))
26
+ } else if (isStartish(topLevelType)) {
27
+ nativeEvent.changedTouches.forEach((touch) => recordTouchStart(touch, touchHistory))
28
+ touchHistory.numberActiveTouches = nativeEvent.touches.length
29
+ if (touchHistory.numberActiveTouches === 1) {
30
+ touchHistory.indexOfSingleActiveTouch = nativeEvent.touches[0].identifier
31
+ }
32
+ } else if (isEndish(topLevelType)) {
33
+ nativeEvent.changedTouches.forEach((touch) => recordTouchEnd(touch, touchHistory))
34
+ touchHistory.numberActiveTouches = nativeEvent.touches.length
35
+ if (touchHistory.numberActiveTouches === 1) {
36
+ const { touchBank } = touchHistory
37
+ for (let i = 0; i < touchBank.length; i++) {
38
+ const touchTrackToCheck = touchBank[i]
39
+ // @ts-ignore
40
+ if (touchTrackToCheck?.touchActive) {
41
+ touchHistory.indexOfSingleActiveTouch = i
42
+ break
43
+ }
44
+ }
45
+ if (process.env.NODE_ENV === 'development') {
46
+ const activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch]
47
+ // @ts-ignore
48
+ if (!activeRecord?.touchActive) {
49
+ console.error('Cannot find single active touch.')
50
+ }
51
+ }
52
+ }
53
+ }
54
+ }
55
+
56
+ get touchHistory(): TouchHistory {
57
+ return this._touchHistory
58
+ }
59
+ }
60
+
61
+ type TouchRecord = {
62
+ currentPageX: number
63
+ currentPageY: number
64
+ currentTimeStamp: number
65
+ previousPageX: number
66
+ previousPageY: number
67
+ previousTimeStamp: number
68
+ startPageX: number
69
+ startPageY: number
70
+ startTimeStamp: number
71
+ touchActive: boolean
72
+ }
73
+
74
+ export type TouchHistory = {
75
+ indexOfSingleActiveTouch: number
76
+ mostRecentTimeStamp: number
77
+ numberActiveTouches: number
78
+ touchBank: Array<TouchRecord>
79
+ }
80
+
81
+ /**
82
+ * Tracks the position and time of each active touch by `touch.identifier`. We
83
+ * should typically only see IDs in the range of 1-20 because IDs get recycled
84
+ * when touches end and start again.
85
+ */
86
+
87
+ const MAX_TOUCH_BANK = 20
88
+
89
+ function timestampForTouch(touch: Touch): number {
90
+ // The legacy internal implementation provides "timeStamp", which has been
91
+ // renamed to "timestamp".
92
+ return touch['timeStamp'] || touch.timestamp
93
+ }
94
+
95
+ /**
96
+ * TODO: Instead of making gestures recompute filtered velocity, we could
97
+ * include a built in velocity computation that can be reused globally.
98
+ */
99
+ function createTouchRecord(touch: Touch): TouchRecord {
100
+ return {
101
+ touchActive: true,
102
+ startPageX: touch.pageX,
103
+ startPageY: touch.pageY,
104
+ startTimeStamp: timestampForTouch(touch),
105
+ currentPageX: touch.pageX,
106
+ currentPageY: touch.pageY,
107
+ currentTimeStamp: timestampForTouch(touch),
108
+ previousPageX: touch.pageX,
109
+ previousPageY: touch.pageY,
110
+ previousTimeStamp: timestampForTouch(touch),
111
+ }
112
+ }
113
+
114
+ function resetTouchRecord(touchRecord: TouchRecord, touch: Touch): void {
115
+ touchRecord.touchActive = true
116
+ touchRecord.startPageX = touch.pageX
117
+ touchRecord.startPageY = touch.pageY
118
+ touchRecord.startTimeStamp = timestampForTouch(touch)
119
+ touchRecord.currentPageX = touch.pageX
120
+ touchRecord.currentPageY = touch.pageY
121
+ touchRecord.currentTimeStamp = timestampForTouch(touch)
122
+ touchRecord.previousPageX = touch.pageX
123
+ touchRecord.previousPageY = touch.pageY
124
+ touchRecord.previousTimeStamp = timestampForTouch(touch)
125
+ }
126
+
127
+ function getTouchIdentifier({ identifier }: Touch): number {
128
+ if (identifier == null) {
129
+ console.error('Touch object is missing identifier.')
130
+ }
131
+ if (process.env.NODE_ENV === 'development') {
132
+ if (identifier > MAX_TOUCH_BANK) {
133
+ console.error(
134
+ 'Touch identifier %s is greater than maximum supported %s which causes ' +
135
+ 'performance issues backfilling array locations for all of the indices.',
136
+ identifier,
137
+ MAX_TOUCH_BANK
138
+ )
139
+ }
140
+ }
141
+ return identifier
142
+ }
143
+
144
+ function recordTouchStart(touch: Touch, touchHistory): void {
145
+ const identifier = getTouchIdentifier(touch)
146
+ const touchRecord = touchHistory.touchBank[identifier]
147
+ if (touchRecord) {
148
+ resetTouchRecord(touchRecord, touch)
149
+ } else {
150
+ touchHistory.touchBank[identifier] = createTouchRecord(touch)
151
+ }
152
+ touchHistory.mostRecentTimeStamp = timestampForTouch(touch)
153
+ }
154
+
155
+ function recordTouchMove(touch: Touch, touchHistory): void {
156
+ const touchRecord = touchHistory.touchBank[getTouchIdentifier(touch)]
157
+ if (touchRecord) {
158
+ touchRecord.touchActive = true
159
+ touchRecord.previousPageX = touchRecord.currentPageX
160
+ touchRecord.previousPageY = touchRecord.currentPageY
161
+ touchRecord.previousTimeStamp = touchRecord.currentTimeStamp
162
+ touchRecord.currentPageX = touch.pageX
163
+ touchRecord.currentPageY = touch.pageY
164
+ touchRecord.currentTimeStamp = timestampForTouch(touch)
165
+ touchHistory.mostRecentTimeStamp = timestampForTouch(touch)
166
+ } else {
167
+ console.warn(
168
+ 'Cannot record touch move without a touch start.\n',
169
+ `Touch Move: ${printTouch(touch)}\n`,
170
+ `Touch Bank: ${printTouchBank(touchHistory)}`
171
+ )
172
+ }
173
+ }
174
+
175
+ function recordTouchEnd(touch: Touch, touchHistory): void {
176
+ const touchRecord = touchHistory.touchBank[getTouchIdentifier(touch)]
177
+ if (touchRecord) {
178
+ touchRecord.touchActive = false
179
+ touchRecord.previousPageX = touchRecord.currentPageX
180
+ touchRecord.previousPageY = touchRecord.currentPageY
181
+ touchRecord.previousTimeStamp = touchRecord.currentTimeStamp
182
+ touchRecord.currentPageX = touch.pageX
183
+ touchRecord.currentPageY = touch.pageY
184
+ touchRecord.currentTimeStamp = timestampForTouch(touch)
185
+ touchHistory.mostRecentTimeStamp = timestampForTouch(touch)
186
+ } else {
187
+ console.warn(
188
+ 'Cannot record touch end without a touch start.\n',
189
+ `Touch End: ${printTouch(touch)}\n`,
190
+ `Touch Bank: ${printTouchBank(touchHistory)}`
191
+ )
192
+ }
193
+ }
194
+
195
+ function printTouch(touch: Touch): string {
196
+ return JSON.stringify({
197
+ identifier: touch.identifier,
198
+ pageX: touch.pageX,
199
+ pageY: touch.pageY,
200
+ timestamp: timestampForTouch(touch),
201
+ })
202
+ }
203
+
204
+ function printTouchBank(touchHistory): string {
205
+ const { touchBank } = touchHistory
206
+ let printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK))
207
+ if (touchBank.length > MAX_TOUCH_BANK) {
208
+ printed += ` (original size: ${touchBank.length})`
209
+ }
210
+ return printed
211
+ }
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Copyright (c) Nicolas Gallagher
3
+ * This source code is licensed under the MIT license found in the
4
+ * LICENSE file in the root directory of this source tree.
5
+ */
6
+
7
+ import type {
8
+ ResponderTouchHistoryStore,
9
+ TouchHistory,
10
+ } from './ResponderTouchHistoryStore'
11
+ import { getBoundingClientRect } from './utils'
12
+
13
+ export type ResponderEvent = {
14
+ bubbles: boolean
15
+ cancelable: boolean
16
+ currentTarget: any
17
+ defaultPrevented: boolean | null
18
+ dispatchConfig: {
19
+ registrationName?: string
20
+ phasedRegistrationNames?: {
21
+ bubbled: string
22
+ captured: string
23
+ }
24
+ }
25
+ eventPhase: number | null
26
+ isDefaultPrevented: () => boolean
27
+ isPropagationStopped: () => boolean
28
+ isTrusted: boolean | null
29
+ preventDefault: () => void
30
+ stopPropagation: () => void
31
+ nativeEvent: TouchEvent
32
+ persist: () => void
33
+ target: any | null
34
+ timeStamp: number
35
+ touchHistory: TouchHistory
36
+ }
37
+
38
+ const emptyFunction = () => {}
39
+ const emptyObject = {}
40
+ const emptyArray = []
41
+
42
+ /**
43
+ * Safari produces very large identifiers that would cause the `touchBank` array
44
+ * length to be so large as to crash the browser, if not normalized like this.
45
+ * In the future the `touchBank` should use an object/map instead.
46
+ */
47
+ function normalizeIdentifier(identifier) {
48
+ return identifier > 20 ? identifier % 20 : identifier
49
+ }
50
+
51
+ /**
52
+ * Converts a native DOM event to a ResponderEvent.
53
+ * Mouse events are transformed into fake touch events.
54
+ */
55
+ export function createResponderEvent(
56
+ domEvent: any,
57
+ responderTouchHistoryStore: ResponderTouchHistoryStore
58
+ ): ResponderEvent {
59
+ let rect
60
+ let propagationWasStopped = false
61
+ let changedTouches
62
+ let touches
63
+
64
+ const domEventChangedTouches = domEvent.changedTouches
65
+ const domEventType = domEvent.type
66
+
67
+ const metaKey = domEvent.metaKey === true
68
+ const shiftKey = domEvent.shiftKey === true
69
+ const force = domEventChangedTouches?.[0].force || 0
70
+ const identifier = normalizeIdentifier(domEventChangedTouches?.[0].identifier || 0)
71
+ const clientX = domEventChangedTouches?.[0].clientX || domEvent.clientX
72
+ const clientY = domEventChangedTouches?.[0].clientY || domEvent.clientY
73
+ const pageX = domEventChangedTouches?.[0].pageX || domEvent.pageX
74
+ const pageY = domEventChangedTouches?.[0].pageY || domEvent.pageY
75
+ const preventDefault =
76
+ typeof domEvent.preventDefault === 'function'
77
+ ? domEvent.preventDefault.bind(domEvent)
78
+ : emptyFunction
79
+ const timestamp = domEvent.timeStamp
80
+
81
+ function normalizeTouches(touches) {
82
+ return Array.prototype.slice.call(touches).map((touch) => {
83
+ return {
84
+ force: touch.force,
85
+ identifier: normalizeIdentifier(touch.identifier),
86
+ get locationX() {
87
+ return locationX(touch.clientX)
88
+ },
89
+ get locationY() {
90
+ return locationY(touch.clientY)
91
+ },
92
+ pageX: touch.pageX,
93
+ pageY: touch.pageY,
94
+ target: touch.target,
95
+ timestamp,
96
+ }
97
+ })
98
+ }
99
+
100
+ if (domEventChangedTouches != null) {
101
+ changedTouches = normalizeTouches(domEventChangedTouches)
102
+ touches = normalizeTouches(domEvent.touches)
103
+ } else {
104
+ const emulatedTouches = [
105
+ {
106
+ force,
107
+ identifier,
108
+ get locationX() {
109
+ return locationX(clientX)
110
+ },
111
+ get locationY() {
112
+ return locationY(clientY)
113
+ },
114
+ pageX,
115
+ pageY,
116
+ target: domEvent.target,
117
+ timestamp,
118
+ },
119
+ ]
120
+ changedTouches = emulatedTouches
121
+ touches =
122
+ domEventType === 'mouseup' || domEventType === 'dragstart'
123
+ ? emptyArray
124
+ : emulatedTouches
125
+ }
126
+
127
+ const responderEvent = {
128
+ bubbles: true,
129
+ cancelable: true,
130
+ // `currentTarget` is set before dispatch
131
+ currentTarget: null,
132
+ defaultPrevented: domEvent.defaultPrevented,
133
+ dispatchConfig: emptyObject,
134
+ eventPhase: domEvent.eventPhase,
135
+ isDefaultPrevented() {
136
+ return domEvent.defaultPrevented
137
+ },
138
+ isPropagationStopped() {
139
+ return propagationWasStopped
140
+ },
141
+ isTrusted: domEvent.isTrusted,
142
+ nativeEvent: {
143
+ altKey: false,
144
+ ctrlKey: false,
145
+ metaKey,
146
+ shiftKey,
147
+ changedTouches,
148
+ force,
149
+ identifier,
150
+ get locationX() {
151
+ return locationX(clientX)
152
+ },
153
+ get locationY() {
154
+ return locationY(clientY)
155
+ },
156
+ pageX,
157
+ pageY,
158
+ target: domEvent.target,
159
+ timestamp,
160
+ touches,
161
+ type: domEventType,
162
+ },
163
+ persist: emptyFunction,
164
+ preventDefault,
165
+ stopPropagation() {
166
+ propagationWasStopped = true
167
+ },
168
+ target: domEvent.target,
169
+ timeStamp: timestamp,
170
+ touchHistory: responderTouchHistoryStore.touchHistory,
171
+ }
172
+
173
+ // Using getters and functions serves two purposes:
174
+ // 1) The value of `currentTarget` is not initially available.
175
+ // 2) Measuring the clientRect may cause layout jank and should only be done on-demand.
176
+ function locationX(x) {
177
+ rect = rect || getBoundingClientRect(responderEvent.currentTarget)
178
+ if (rect) {
179
+ return x - rect.left
180
+ }
181
+ }
182
+ function locationY(y) {
183
+ rect = rect || getBoundingClientRect(responderEvent.currentTarget)
184
+ if (rect) {
185
+ return y - rect.top
186
+ }
187
+ }
188
+
189
+ return responderEvent as any
190
+ }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './useResponderEvents'
package/src/types.ts ADDED
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Copyright (c) Nicolas Gallagher
3
+ * This source code is licensed under the MIT license found in the
4
+ * LICENSE file in the root directory of this source tree.
5
+ */
6
+
7
+ export type Touch = {
8
+ force: number
9
+ identifier: number
10
+ // The locationX and locationY properties are non-standard additions
11
+ locationX: any
12
+ locationY: any
13
+ pageX: number
14
+ pageY: number
15
+ target: any
16
+ // Touches in a list have a timestamp property
17
+ timestamp: number
18
+ }
19
+
20
+ export type TouchEvent = {
21
+ altKey: boolean
22
+ ctrlKey: boolean
23
+ metaKey: boolean
24
+ shiftKey: boolean
25
+ // TouchList is an array in the Responder system
26
+ changedTouches: Array<Touch>
27
+ force: number
28
+ // React Native adds properties to the "nativeEvent that are usually only found on W3C Touches ‾\_(ツ)_/‾
29
+ identifier: number
30
+ locationX: any
31
+ locationY: any
32
+ pageX: number
33
+ pageY: number
34
+ target: any
35
+ // The timestamp has a lowercase "s" in the Responder system
36
+ timestamp: number
37
+ // TouchList is an array in the Responder system
38
+ touches: Array<Touch>
39
+ }
40
+
41
+ export const BLUR = 'blur'
42
+ export const CONTEXT_MENU = 'contextmenu'
43
+ export const FOCUS_OUT = 'focusout'
44
+ export const MOUSE_DOWN = 'mousedown'
45
+ export const MOUSE_MOVE = 'mousemove'
46
+ export const MOUSE_UP = 'mouseup'
47
+ export const MOUSE_CANCEL = 'dragstart'
48
+ export const TOUCH_START = 'touchstart'
49
+ export const TOUCH_MOVE = 'touchmove'
50
+ export const TOUCH_END = 'touchend'
51
+ export const TOUCH_CANCEL = 'touchcancel'
52
+ export const SCROLL = 'scroll'
53
+ export const SELECT = 'select'
54
+ export const SELECTION_CHANGE = 'selectionchange'
55
+
56
+ export function isStartish(eventType: unknown): boolean {
57
+ return eventType === TOUCH_START || eventType === MOUSE_DOWN
58
+ }
59
+
60
+ export function isMoveish(eventType: unknown): boolean {
61
+ return eventType === TOUCH_MOVE || eventType === MOUSE_MOVE
62
+ }
63
+
64
+ export function isEndish(eventType: unknown): boolean {
65
+ return eventType === TOUCH_END || eventType === MOUSE_UP || isCancelish(eventType)
66
+ }
67
+
68
+ export function isCancelish(eventType: unknown): boolean {
69
+ return eventType === TOUCH_CANCEL || eventType === MOUSE_CANCEL
70
+ }
71
+
72
+ export function isScroll(eventType: unknown): boolean {
73
+ return eventType === SCROLL
74
+ }
75
+
76
+ export function isSelectionChange(eventType: unknown): boolean {
77
+ return eventType === SELECT || eventType === SELECTION_CHANGE
78
+ }
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Copyright (c) Nicolas Gallagher
3
+ * This source code is licensed under the MIT license found in the
4
+ * LICENSE file in the root directory of this source tree.
5
+ */
6
+
7
+ import * as React from 'react'
8
+
9
+ import * as ResponderSystem from './ResponderSystem'
10
+
11
+ export * from './utils'
12
+
13
+ const emptyObject = {}
14
+
15
+ const Attached = new WeakMap<any, boolean>()
16
+ const Ids = new WeakMap<any, string>()
17
+
18
+ export function useResponderEvents(
19
+ hostRef: any,
20
+ configIn: ResponderSystem.ResponderConfig = emptyObject
21
+ ) {
22
+ const config = getResponderConfigIfDefined(configIn)
23
+ // hanzo-gui + rnw compat
24
+ const node = hostRef?.current?.host || hostRef?.current
25
+
26
+ // Register and unregister with the Responder System as necessary
27
+ React.useEffect(() => {
28
+ if (config === emptyObject) return
29
+
30
+ ResponderSystem.attachListeners()
31
+
32
+ if (!Ids.has(hostRef)) {
33
+ Ids.set(hostRef, `${Math.random()}`)
34
+ }
35
+ const id = Ids.get(hostRef)!
36
+
37
+ ResponderSystem.addNode(id, node, config)
38
+ Attached.set(hostRef, true)
39
+
40
+ return () => {
41
+ ResponderSystem.removeNode(node)
42
+ Attached.set(hostRef, false)
43
+ }
44
+ }, [config, hostRef])
45
+
46
+ if (process.env.NODE_ENV === 'development') {
47
+ React.useDebugValue({
48
+ isResponder: node === ResponderSystem.getResponderNode(),
49
+ })
50
+ React.useDebugValue(config)
51
+ }
52
+ }
53
+
54
+ export function getResponderConfigIfDefined({
55
+ onMoveShouldSetResponder,
56
+ onMoveShouldSetResponderCapture,
57
+ onResponderEnd,
58
+ onResponderGrant,
59
+ onResponderMove,
60
+ onResponderReject,
61
+ onResponderRelease,
62
+ onResponderStart,
63
+ onResponderTerminate,
64
+ onResponderTerminationRequest,
65
+ onScrollShouldSetResponder,
66
+ onScrollShouldSetResponderCapture,
67
+ onSelectionChangeShouldSetResponder,
68
+ onSelectionChangeShouldSetResponderCapture,
69
+ onStartShouldSetResponder,
70
+ onStartShouldSetResponderCapture,
71
+ }: ResponderSystem.ResponderConfig): ResponderSystem.ResponderConfig {
72
+ return onMoveShouldSetResponder ||
73
+ onMoveShouldSetResponderCapture ||
74
+ onResponderEnd ||
75
+ onResponderGrant ||
76
+ onResponderMove ||
77
+ onResponderReject ||
78
+ onResponderRelease ||
79
+ onResponderStart ||
80
+ onResponderTerminate ||
81
+ onResponderTerminationRequest ||
82
+ onScrollShouldSetResponder ||
83
+ onScrollShouldSetResponderCapture ||
84
+ onSelectionChangeShouldSetResponder ||
85
+ onSelectionChangeShouldSetResponderCapture ||
86
+ onStartShouldSetResponder ||
87
+ onStartShouldSetResponderCapture
88
+ ? {
89
+ onMoveShouldSetResponder,
90
+ onMoveShouldSetResponderCapture,
91
+ onResponderEnd,
92
+ onResponderGrant,
93
+ onResponderMove,
94
+ onResponderReject,
95
+ onResponderRelease,
96
+ onResponderStart,
97
+ onResponderTerminate,
98
+ onResponderTerminationRequest,
99
+ onScrollShouldSetResponder,
100
+ onScrollShouldSetResponderCapture,
101
+ onSelectionChangeShouldSetResponder,
102
+ onSelectionChangeShouldSetResponderCapture,
103
+ onStartShouldSetResponder,
104
+ onStartShouldSetResponderCapture,
105
+ }
106
+ : emptyObject
107
+ }