@@ -7,251 +7,165 @@ Event components do not render a host node. They listen to native browser events
77dispatched on the host node of their child and transform those events into
88high-level events for applications.
99
10+ The core API is documented below. Documentation for individual Event Components
11+ can be found [ here] ( ./docs ) .
1012
11- ## Focus
13+ ## EventComponent
1214
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:
1617
1718``` 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+ | };
2725```
2826
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+
2933``` 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,
3249 target: Element ,
33- type : ' blur ' | ' focus ' | ' focuschange '
50+ ...
3451}
3552```
3653
37- ### disabled: boolean
38-
39- Disables all ` Focus ` events.
54+ ### createInitialState?: (props: null | Object) => Object
4055
41- ### onBlur: (e: FocusEvent) => void
56+ The initial state of that the Event Component is created with.
4257
43- Called when the element loses focus.
58+ ### onEvent?: (event: ResponderEvent, context: ResponderContext, props, state)
4459
45- ### onFocus: (e: FocusEvent) => void
60+ Called during the bubble phase of the ` targetEventTypes ` dispatched on DOM
61+ elements within the Event Component.
4662
47- Called when the element gains focus.
63+ ### onEventCapture?: (event: ResponderEvent, context: ResponderContext, props, state)
4864
49- ### onFocusChange: boolean => void
65+ Called during the capture phase of the ` targetEventTypes ` dispatched on DOM
66+ elements within the Event Component.
5067
51- Called when the element changes hover state (i.e., after ` onBlur ` and
52- ` onFocus ` ).
68+ ### onMount?: (context: ResponderContext, props, state)
5369
70+ Called after an Event Component in mounted.
5471
55- ## Hover
72+ ### onOwnershipChange?: (context: ResponderContext, props, state)
5673
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.
8875
89- ### delayHoverEnd: number
76+ ### onRootEvent?: (event: ResponderEvent, context: ResponderContext, props, state)
9077
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.
9379
94- ### delayHoverStart: number
80+ ### onUnmount?: (context: ResponderContext, props, state)
9581
96- The duration of the delay between when hover starts and when ` onHoverStart ` is
97- called.
82+ Called before an Event Component in unmounted.
9883
99- ### disabled: boolean
84+ ### rootEventTypes?: Array< ResponderEventType >
10085
101- Disables all ` Hover ` events.
86+ Defines the DOM events to listen to on the root of the app .
10287
103- ### onHoverChange : boolean => void
88+ ### stopLocalPropagation : boolean
10489
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.
10793
108- ### onHoverEnd: (e: HoverEvent) => void
94+ ### targetEventTypes?: Array< ResponderEventType >
10995
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.
11297
113- ### onHoverMove: (e: HoverEvent) => void
11498
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
117100
118- ### onHoverStart: (e: HoverEvent) => void
101+ The Event Responder Context is exposed via the ` context ` argument for certain methods
102+ on the ` EventResponder ` object.
119103
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 >)
123105
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.
125108
126- Whether to ` preventDefault() ` native events.
109+ ### clearTimeout(id: Symbol): void
127110
111+ Clear a timeout defined using ` context.setTimeout ` .
128112
129- ## Press
113+ ### dispatchEvent(event: CustomEvent, listener, { discrete: boolean })
130114
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:
137118
138119``` 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 });
160122```
161123
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 >
188125
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.
192128
193- ### disabled : boolean
129+ ### hasOwnership() : boolean
194130
195- Disables all ` Press ` events .
131+ Returns ` true ` if the instance has taken ownership of the responder .
196132
197- ### onLongPress: (e: PressEvent) => void
133+ ### isPositionWithinTouchHitTarget(x: number, y: number): boolean
198134
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.
201136
202- ### onLongPressChange: boolean => void
137+ ### isTargetDirectlyWithinEventComponent(target: Element): boolean
203138
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 .
205140
206- ### onLongPressShouldCancelPress: () => boolean
141+ ### isTargetWithinElement(target: Element, element: Element): boolean
207142
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 ` .
210144
211- ### onPress: (e: PressEvent) => void
145+ ### isTargetWithinEventComponent(target: Element): boolean
212146
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.
218148
219- ### onPressChange: boolean => void
149+ ### isTargetWithinEventResponderScope(target: Element): boolean
220150
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.
223152
224- ### onPressEnd: (e: PressEvent) => void
153+ ### releaseOwnership(): boolean
225154
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.
230156
231- ### onPressMove: (e: PressEvent) => void
157+ ### removeRootEventTypes(eventTypes: Array< ResponderEventType >)
232158
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 ` .
236160
237- ### onPressStart: (e: PressEvent) => void
161+ ### requestGlobalOwnership(): boolean
238162
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.
242164
243- ### pressRetentionOffset: PressOffset
165+ ### requestResponderOwnership(): boolean
244166
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.
249168
250- ### preventDefault: boolean = true
169+ ### setTimeout(func: () => void, delay: number): Symbol
251170
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