@@ -7,251 +7,165 @@ Event components do not render a host node. They listen to native browser events
7
7
dispatched on the host node of their child and transform those events into
8
8
high-level events for applications.
9
9
10
+ The core API is documented below. Documentation for individual Event Components
11
+ can be found [ here] ( ./docs ) .
10
12
11
- ## Focus
13
+ ## EventComponent
12
14
13
- The ` Focus ` module responds to focus and blur events on the element it wraps.
14
- Focus events are dispatched for ` mouse ` , ` pen ` , ` touch ` , and ` keyboard `
15
- pointer types.
15
+ An Event Component is defined by a module that exports an object of the
16
+ following type:
16
17
17
18
``` js
18
- // Example
19
- const TextField = (props ) => (
20
- < Focus
21
- onBlur= {props .onBlur }
22
- onFocus= {props .onFocus }
23
- >
24
- < textarea>< / textarea>
25
- < / Focus>
26
- );
19
+ type EventComponent = {|
20
+ $$typeof: REACT_EVENT_COMPONENT_TYPE ,
21
+ displayName?: string,
22
+ props: null | Object ,
23
+ responder: EventResponder,
24
+ | };
27
25
```
28
26
27
+ ## EventResponder
28
+
29
+ An Event Responder is defined using an object. Each responder can define DOM
30
+ events to listen to, handle the synthetic responder events, dispatch custom
31
+ events, and implement a state machine.
32
+
29
33
``` js
30
- // Types
31
- type FocusEvent = {
34
+ // types
35
+ type ResponderEventType =
36
+ | string
37
+ | {name: string, passive?: boolean, capture?: boolean};
38
+
39
+ type ResponderEvent = {|
40
+ nativeEvent: any,
41
+ target: Element | Document ,
42
+ type: string,
43
+ passive: boolean,
44
+ passiveSupported: boolean,
45
+ | };
46
+
47
+ type CustomEvent = {
48
+ type: string,
32
49
target: Element ,
33
- type : ' blur ' | ' focus ' | ' focuschange '
50
+ ...
34
51
}
35
52
```
36
53
37
- ### disabled: boolean
38
-
39
- Disables all ` Focus ` events.
54
+ ### createInitialState?: (props: null | Object) => Object
40
55
41
- ### onBlur: (e: FocusEvent) => void
56
+ The initial state of that the Event Component is created with.
42
57
43
- Called when the element loses focus.
58
+ ### onEvent?: (event: ResponderEvent, context: ResponderContext, props, state)
44
59
45
- ### onFocus: (e: FocusEvent) => void
60
+ Called during the bubble phase of the ` targetEventTypes ` dispatched on DOM
61
+ elements within the Event Component.
46
62
47
- Called when the element gains focus.
63
+ ### onEventCapture?: (event: ResponderEvent, context: ResponderContext, props, state)
48
64
49
- ### onFocusChange: boolean => void
65
+ Called during the capture phase of the ` targetEventTypes ` dispatched on DOM
66
+ elements within the Event Component.
50
67
51
- Called when the element changes hover state (i.e., after ` onBlur ` and
52
- ` onFocus ` ).
68
+ ### onMount?: (context: ResponderContext, props, state)
53
69
70
+ Called after an Event Component in mounted.
54
71
55
- ## Hover
72
+ ### onOwnershipChange?: (context: ResponderContext, props, state)
56
73
57
- The ` Hover ` module responds to hover events on the element it wraps. Hover
58
- events are only dispatched for ` mouse ` pointer types. Hover begins when the
59
- pointer enters the element's bounds and ends when the pointer leaves.
60
-
61
- ``` js
62
- // Example
63
- const Link = (props ) => (
64
- const [ hovered , setHovered ] = useState (false );
65
- return (
66
- < Hover onHoverChange= {setHovered}>
67
- < a
68
- {... props}
69
- href= {props .href }
70
- style= {{
71
- ... props .style ,
72
- textDecoration: hovered ? ' underline' : ' none'
73
- }}
74
- / >
75
- < / Hover>
76
- );
77
- );
78
- ```
79
-
80
- ``` js
81
- // Types
82
- type HoverEvent = {
83
- pointerType: ' mouse' ,
84
- target: Element ,
85
- type: ' hoverstart' | ' hoverend' | ' hovermove' | ' hoverchange'
86
- }
87
- ```
74
+ Called when responder ownership is granted or terminated for an Event Component instance.
88
75
89
- ### delayHoverEnd: number
76
+ ### onRootEvent?: (event: ResponderEvent, context: ResponderContext, props, state)
90
77
91
- The duration of the delay between when hover ends and when ` onHoverEnd ` is
92
- called.
78
+ Called when any of the ` rootEventTypes ` are dispatched on the root of the app.
93
79
94
- ### delayHoverStart: number
80
+ ### onUnmount?: (context: ResponderContext, props, state)
95
81
96
- The duration of the delay between when hover starts and when ` onHoverStart ` is
97
- called.
82
+ Called before an Event Component in unmounted.
98
83
99
- ### disabled: boolean
84
+ ### rootEventTypes?: Array< ResponderEventType >
100
85
101
- Disables all ` Hover ` events.
86
+ Defines the DOM events to listen to on the root of the app .
102
87
103
- ### onHoverChange : boolean => void
88
+ ### stopLocalPropagation : boolean
104
89
105
- Called when the element changes hover state (i.e., after ` onHoverStart ` and
106
- ` onHoverEnd ` ).
90
+ Defines whether or not synthetic events propagate to other Event Components * of
91
+ the same type* . This has no effect on propagation of the source DOM events or
92
+ the synthetic events dispatched to Event Components of different types.
107
93
108
- ### onHoverEnd: (e: HoverEvent) => void
94
+ ### targetEventTypes?: Array< ResponderEventType >
109
95
110
- Called once the element is no longer hovered. It will be cancelled if the
111
- pointer leaves the element before the ` delayHoverStart ` threshold is exceeded.
96
+ Defines the DOM events to listen to within the Event Component subtree.
112
97
113
- ### onHoverMove: (e: HoverEvent) => void
114
98
115
- Called when the pointer moves within the hit bounds of the element. ` onHoverMove ` is
116
- called immediately and doesn't wait for delayed ` onHoverStart ` .
99
+ ## ResponderContext
117
100
118
- ### onHoverStart: (e: HoverEvent) => void
101
+ The Event Responder Context is exposed via the ` context ` argument for certain methods
102
+ on the ` EventResponder ` object.
119
103
120
- Called once the element is hovered. It will not be called if the pointer leaves
121
- the element before the ` delayHoverStart ` threshold is exceeded. And it will not
122
- be called more than once before ` onHoverEnd ` is called.
104
+ ### addRootEventTypes(eventTypes: Array<ResponderEventType >)
123
105
124
- ### preventDefault: boolean = true
106
+ This can be used to dynamically listen to events on the root of the app only
107
+ when it is necessary to do so.
125
108
126
- Whether to ` preventDefault() ` native events.
109
+ ### clearTimeout(id: Symbol): void
127
110
111
+ Clear a timeout defined using ` context.setTimeout ` .
128
112
129
- ## Press
113
+ ### dispatchEvent(event: CustomEvent, listener, { discrete: boolean })
130
114
131
- The ` Press ` module responds to press events on the element it wraps. Press
132
- events are dispatched for ` mouse ` , ` pen ` , ` touch ` , and ` keyboard ` pointer types.
133
- Press events are only dispatched for keyboards when pressing the Enter or
134
- Spacebar keys. If neither ` onPress ` nor ` onLongPress ` are called, this signifies
135
- that the press ended outside of the element hit bounds (i.e., the user aborted
136
- the press).
115
+ Dispatches a custom synthetic event. The ` type ` and ` target ` are required
116
+ fields, but any other fields can be defined on the ` event ` that will be passed
117
+ to the ` listener ` . For example:
137
118
138
119
``` js
139
- // Example
140
- const Button = (props ) => (
141
- const [ pressed , setPressed ] = useState (false );
142
- return (
143
- < Press
144
- onPress= {props .onPress }
145
- onPressChange= {setPressed}
146
- onLongPress= {props .onLongPress }
147
- >
148
- < div
149
- {... props}
150
- role= " button"
151
- tabIndex= {0 }
152
- style= {
153
- ... buttonStyles,
154
- ... (pressed && pressedStyles)
155
- }}
156
- / >
157
- < / Press>
158
- );
159
- );
120
+ const event = { type: ' press' , target, pointerType, x, y };
121
+ context .dispatchEvent (event , props .onPress , { discrete: true });
160
122
```
161
123
162
- ``` js
163
- // Types
164
- type PressEvent = {
165
- pointerType: ' mouse' | ' touch' | ' pen' | ' keyboard' ,
166
- target: Element ,
167
- type: ' press' | ' pressstart' | ' pressend' | ' presschange' | ' pressmove' | ' longpress' | ' longpresschange'
168
- }
169
-
170
- type PressOffset = {
171
- top: number,
172
- right: number,
173
- bottom: number,
174
- right: number
175
- };
176
- ```
177
-
178
- ### delayLongPress: number = 500ms
179
-
180
- The duration of a press before ` onLongPress ` and ` onLongPressChange ` are called.
181
-
182
- ### delayPressEnd: number
183
-
184
- The duration of the delay between when the press ends and when ` onPressEnd ` is
185
- called.
186
-
187
- ### delayPressStart: number
124
+ ### getFocusableElementsInScope(): Array<Element >
188
125
189
- The duration of a delay between when the press starts and when ` onPressStart ` is
190
- called. This delay is cut short (and ` onPressStart ` is called) if the press is
191
- released before the threshold is exceeded.
126
+ Returns every DOM element that can be focused within the scope of the Event
127
+ Component instance.
192
128
193
- ### disabled : boolean
129
+ ### hasOwnership() : boolean
194
130
195
- Disables all ` Press ` events .
131
+ Returns ` true ` if the instance has taken ownership of the responder .
196
132
197
- ### onLongPress: (e: PressEvent) => void
133
+ ### isPositionWithinTouchHitTarget(x: number, y: number): boolean
198
134
199
- Called once the element has been pressed for the length of ` delayLongPress ` . If
200
- the press point moves more than 10px ` onLongPress ` is cancelled.
135
+ Returns ` true ` if the global coordinates lie within the TouchHitTarget.
201
136
202
- ### onLongPressChange: boolean => void
137
+ ### isTargetDirectlyWithinEventComponent(target: Element): boolean
203
138
204
- Called when the element changes long-press state .
139
+ Returns ` true ` is the target element is within the direct subtree of the Event Component instance, i.e., the target is not nested within an Event Component instance that is a descendant of the current instance .
205
140
206
- ### onLongPressShouldCancelPress: () => boolean
141
+ ### isTargetWithinElement(target: Element, element: Element): boolean
207
142
208
- Determines whether calling ` onPress ` should be cancelled if ` onLongPress ` or
209
- ` onLongPressChange ` have already been called. Default is ` false ` .
143
+ Returns ` true ` if ` target ` is a child of ` element ` .
210
144
211
- ### onPress: (e: PressEvent) => void
145
+ ### isTargetWithinEventComponent(target: Element): boolean
212
146
213
- Called immediately after a press is released, unless either 1) the press is
214
- released outside the hit bounds of the element (accounting for
215
- ` pressRetentionOffset ` and ` TouchHitTarget ` ), or 2) the press was a long press,
216
- and ` onLongPress ` or ` onLongPressChange ` props are provided, and
217
- ` onLongPressCancelsPress() ` is ` true ` .
147
+ Returns ` true ` is the target element is within the subtree of the Event Component instance.
218
148
219
- ### onPressChange: boolean => void
149
+ ### isTargetWithinEventResponderScope(target: Element): boolean
220
150
221
- Called when the element changes press state (i.e., after ` onPressStart ` and
222
- ` onPressEnd ` ).
151
+ Returns ` true ` is the target element is within the current responder.
223
152
224
- ### onPressEnd: (e: PressEvent) => void
153
+ ### releaseOwnership(): boolean
225
154
226
- Called once the element is no longer pressed (because it was released, or moved
227
- beyond the hit bounds). If the press starts again before the ` delayPressEnd `
228
- threshold is exceeded then the delay is reset to prevent ` onPressEnd ` being
229
- called during a press.
155
+ Returns ` true ` if the instance released ownership of the responder.
230
156
231
- ### onPressMove: (e: PressEvent) => void
157
+ ### removeRootEventTypes(eventTypes: Array< ResponderEventType >)
232
158
233
- Called when a press moves within the hit bounds of the element. ` onPressMove ` is
234
- called immediately and doesn't wait for delayed ` onPressStart ` . Never called for
235
- keyboard-initiated press events.
159
+ Remove the root event types added with ` addRootEventTypes ` .
236
160
237
- ### onPressStart: (e: PressEvent) => void
161
+ ### requestGlobalOwnership(): boolean
238
162
239
- Called once the element is pressed down. If the press is released before the
240
- ` delayPressStart ` threshold is exceeded then the delay is cut short and
241
- ` onPressStart ` is called immediately.
163
+ Request ownership of the global responder.
242
164
243
- ### pressRetentionOffset: PressOffset
165
+ ### requestResponderOwnership(): boolean
244
166
245
- Defines how far the pointer (while held down) may move outside the bounds of the
246
- element before it is deactivated. Once deactivated, the pointer (still held
247
- down) can be moved back within the bounds of the element to reactivate it.
248
- Ensure you pass in a constant to reduce memory allocations.
167
+ Request ownership of the responder.
249
168
250
- ### preventDefault: boolean = true
169
+ ### setTimeout(func: () => void, delay: number): Symbol
251
170
252
- Whether to ` preventDefault() ` native events. Native behavior is prevented by
253
- default. If an anchor is the child of ` Press ` , internal and external navigation
254
- should be performed in ` onPress ` /` onLongPress ` . To rely on native behavior
255
- instead, set ` preventDefault ` to ` false ` , but be aware that native behavior will
256
- take place immediately after interaction without respect for delays or long
257
- press.
171
+ This can be used to dispatch async events, e.g., those that fire after a delay.
0 commit comments