[Flare] Remove delay props from Hover (#16248)
Moving working with delays into user-space.
Nicolas Gallagher committed
Jul 30, 2019 at 09:29 UTC
e276a5e85046c2cf336f623d975b1af01b251b5e
3 files changed
+5
-259
packages/react-events/docs/Hover.md
+3
-17
@@ -37,16 +37,6 @@ type HoverEvent = {
37
38
## Props
39
40
-### delayHoverEnd: number
41
-
42
-The duration of the delay between when hover ends and when `onHoverEnd` is
43
-called.
44
-
45
-### delayHoverStart: number
46
-
47
-The duration of the delay between when hover starts and when `onHoverStart` is
48
-called.
49
-
40
### disabled: boolean
41
42
Disables all `Hover` events.
@@ -58,19 +48,15 @@ Called when the element changes hover state (i.e., after `onHoverStart` and
48
49
### onHoverEnd: (e: HoverEvent) => void
50
61
-Called once the element is no longer hovered. It will be cancelled if the
62
-pointer leaves the element before the `delayHoverStart` threshold is exceeded.
51
+Called once the element is no longer hovered.
52
53
### onHoverMove: (e: HoverEvent) => void
54
66
-Called when the pointer moves within the hit bounds of the element. `onHoverMove` is
67
-called immediately and doesn't wait for delayed `onHoverStart`.
55
+Called when the pointer moves within the hit bounds of the element.
56
57
### onHoverStart: (e: HoverEvent) => void
58
71
-Called once the element is hovered. It will not be called if the pointer leaves
72
-the element before the `delayHoverStart` threshold is exceeded. And it will not
73
-be called more than once before `onHoverEnd` is called.
59
+Called once the element is hovered.
60
61
### preventDefault: boolean = true
62
packages/react-events/src/dom/Hover.js
+2
-43
@@ -24,8 +24,6 @@ type HoverListenerProps = {|
24
25
type HoverProps = {
26
disabled: boolean,
27
- delayHoverEnd: number,
28
- delayHoverStart: number,
27
preventDefault: boolean,
28
};
29
@@ -55,9 +53,6 @@ type HoverEvent = {|
53
y: null | number,
54
|};
55
58
-const DEFAULT_HOVER_END_DELAY_MS = 0;
59
-const DEFAULT_HOVER_START_DELAY_MS = 0;
60
-
56
const targetEventTypes = [
57
'pointerover',
58
'pointermove',
@@ -136,7 +131,7 @@ function dispatchHoverStartEvents(
131
state.hoverEndTimeout = null;
132
}
133
139
- const activate = () => {
134
+ if (!state.isActiveHovered) {
135
state.isActiveHovered = true;
136
const syntheticEvent = createHoverEvent(
137
event,
@@ -146,22 +141,6 @@ function dispatchHoverStartEvents(
141
);
142
context.dispatchEvent('onHoverStart', syntheticEvent, UserBlockingEvent);
143
dispatchHoverChangeEvent(event, context, props, state);
149
- };
150
-
151
- if (!state.isActiveHovered) {
152
- const delayHoverStart = calculateDelayMS(
153
- props.delayHoverStart,
154
- 0,
155
- DEFAULT_HOVER_START_DELAY_MS,
156
- );
157
- if (delayHoverStart > 0) {
158
- state.hoverStartTimeout = context.setTimeout(() => {
159
- state.hoverStartTimeout = null;
160
- activate();
161
- }, delayHoverStart);
162
- } else {
163
- activate();
164
- }
144
}
145
}
146
@@ -188,7 +167,7 @@ function dispatchHoverEndEvents(
167
state.hoverStartTimeout = null;
168
}
169
191
- const deactivate = () => {
170
+ if (state.isActiveHovered) {
171
state.isActiveHovered = false;
172
173
const syntheticEvent = createHoverEvent(
@@ -202,29 +181,9 @@ function dispatchHoverEndEvents(
181
state.hoverTarget = null;
182
state.ignoreEmulatedMouseEvents = false;
183
state.isTouched = false;
205
- };
206
-
207
- if (state.isActiveHovered) {
208
- const delayHoverEnd = calculateDelayMS(
209
- props.delayHoverEnd,
210
- 0,
211
- DEFAULT_HOVER_END_DELAY_MS,
212
- );
213
- if (delayHoverEnd > 0) {
214
- state.hoverEndTimeout = context.setTimeout(() => {
215
- deactivate();
216
- }, delayHoverEnd);
217
- } else {
218
- deactivate();
219
- }
184
}
185
}
186
223
-function calculateDelayMS(delay: ?number, min = 0, fallback = 0) {
224
- const maybeNumber = delay == null ? null : delay;
225
- return Math.max(min, maybeNumber != null ? maybeNumber : fallback);
226
-}
227
-
187
function unmountResponder(
188
context: ReactDOMResponderContext,
189
props: HoverProps,
packages/react-events/src/dom/__tests__/Hover-test.internal.js
-199
@@ -167,97 +167,6 @@ describe('Hover event responder', () => {
167
);
168
expect(onHoverStart).not.toBeCalled();
169
});
170
-
171
- describe('delayHoverStart', () => {
172
- it('can be configured', () => {
173
- const Component = () => {
174
- useHoverListener({
175
- onHoverStart: onHoverStart,
176
- });
177
- return (
178
- <div
179
- ref={ref}
180
- responders={<HoverResponder delayHoverStart={2000} />}
181
- />
182
- );
183
- };
184
- ReactDOM.render(<Component />, container);
185
-
186
- ref.current.dispatchEvent(createEvent('pointerover'));
187
- jest.advanceTimersByTime(1999);
188
- expect(onHoverStart).not.toBeCalled();
189
- jest.advanceTimersByTime(1);
190
- expect(onHoverStart).toHaveBeenCalledTimes(1);
191
- });
192
-
193
- it('is reset if "pointerout" is dispatched during a delay', () => {
194
- const Component = () => {
195
- useHoverListener({
196
- onHoverStart: onHoverStart,
197
- });
198
- return (
199
- <div
200
- ref={ref}
201
- responders={<HoverResponder delayHoverStart={500} />}
202
- />
203
- );
204
- };
205
- ReactDOM.render(<Component />, container);
206
-
207
- ref.current.dispatchEvent(createEvent('pointerover'));
208
- jest.advanceTimersByTime(499);
209
- ref.current.dispatchEvent(createEvent('pointerout'));
210
- jest.advanceTimersByTime(1);
211
- expect(onHoverStart).not.toBeCalled();
212
- ref.current.dispatchEvent(createEvent('pointerover'));
213
- jest.runAllTimers();
214
- expect(onHoverStart).toHaveBeenCalledTimes(1);
215
- });
216
-
217
- it('onHoverStart is called synchronously if delay is 0ms', () => {
218
- const Component = () => {
219
- useHoverListener({
220
- onHoverStart: onHoverStart,
221
- });
222
- return (
223
- <div
224
- ref={ref}
225
- responders={<HoverResponder delayHoverStart={0} />}
226
- />
227
- );
228
- };
229
- ReactDOM.render(<Component />, container);
230
-
231
- ref.current.dispatchEvent(createEvent('pointerover'));
232
- expect(onHoverStart).toHaveBeenCalledTimes(1);
233
- });
234
-
235
- it('onHoverStart is only called once per active hover', () => {
236
- const Component = () => {
237
- useHoverListener({
238
- onHoverStart: onHoverStart,
239
- });
240
- return (
241
- <div
242
- ref={ref}
243
- responders={
244
- <HoverResponder delayHoverStart={500} delayHoverEnd={100} />
245
- }
246
- />
247
- );
248
- };
249
- ReactDOM.render(<Component />, container);
250
-
251
- ref.current.dispatchEvent(createEvent('pointerover'));
252
- jest.advanceTimersByTime(500);
253
- expect(onHoverStart).toHaveBeenCalledTimes(1);
254
- ref.current.dispatchEvent(createEvent('pointerout'));
255
- jest.advanceTimersByTime(10);
256
- ref.current.dispatchEvent(createEvent('pointerover'));
257
- jest.runAllTimers();
258
- expect(onHoverStart).toHaveBeenCalledTimes(1);
259
- });
260
- });
170
});
171
172
describe('onHoverChange', () => {
@@ -399,114 +308,6 @@ describe('Hover event responder', () => {
308
ref.current.dispatchEvent(createEvent('mouseout'));
309
expect(onHoverEnd).not.toBeCalled();
310
});
402
-
403
- describe('delayHoverEnd', () => {
404
- it('can be configured', () => {
405
- const Component = () => {
406
- useHoverListener({
407
- onHoverEnd,
408
- });
409
- return (
410
- <div
411
- ref={ref}
412
- responders={<HoverResponder delayHoverEnd={2000} />}
413
- />
414
- );
415
- };
416
- ReactDOM.render(<Component />, container);
417
-
418
- ref.current.dispatchEvent(createEvent('pointerover'));
419
- ref.current.dispatchEvent(createEvent('pointerout'));
420
- jest.advanceTimersByTime(1999);
421
- expect(onHoverEnd).not.toBeCalled();
422
- jest.advanceTimersByTime(1);
423
- expect(onHoverEnd).toHaveBeenCalledTimes(1);
424
- });
425
-
426
- it('delayHoverEnd is called synchronously if delay is 0ms', () => {
427
- const Component = () => {
428
- useHoverListener({
429
- onHoverEnd,
430
- });
431
- return (
432
- <div ref={ref} responders={<HoverResponder delayHoverEnd={0} />} />
433
- );
434
- };
435
- ReactDOM.render(<Component />, container);
436
-
437
- ref.current.dispatchEvent(createEvent('pointerover'));
438
- ref.current.dispatchEvent(createEvent('pointerout'));
439
- expect(onHoverEnd).toHaveBeenCalledTimes(1);
440
- });
441
-
442
- it('onHoverEnd is only called once per active hover', () => {
443
- const Component = () => {
444
- useHoverListener({
445
- onHoverEnd,
446
- });
447
- return (
448
- <div
449
- ref={ref}
450
- responders={<HoverResponder delayHoverEnd={500} />}
451
- />
452
- );
453
- };
454
- ReactDOM.render(<Component />, container);
455
-
456
- ref.current.dispatchEvent(createEvent('pointerover'));
457
- ref.current.dispatchEvent(createEvent('pointerout'));
458
- jest.advanceTimersByTime(499);
459
- ref.current.dispatchEvent(createEvent('pointerover'));
460
- jest.advanceTimersByTime(100);
461
- ref.current.dispatchEvent(createEvent('pointerout'));
462
- jest.runAllTimers();
463
- expect(onHoverEnd).toHaveBeenCalledTimes(1);
464
- });
465
-
466
- it('onHoverEnd is not called if "pointerover" is dispatched during a delay', () => {
467
- const Component = () => {
468
- useHoverListener({
469
- onHoverEnd,
470
- });
471
- return (
472
- <div
473
- ref={ref}
474
- responders={<HoverResponder delayHoverEnd={500} />}
475
- />
476
- );
477
- };
478
- ReactDOM.render(<Component />, container);
479
-
480
- ref.current.dispatchEvent(createEvent('pointerover'));
481
- ref.current.dispatchEvent(createEvent('pointerout'));
482
- jest.advanceTimersByTime(499);
483
- ref.current.dispatchEvent(createEvent('pointerover'));
484
- jest.advanceTimersByTime(1);
485
- expect(onHoverEnd).not.toBeCalled();
486
- });
487
-
488
- it('onHoverEnd is not called if there was no active hover', () => {
489
- const Component = () => {
490
- useHoverListener({
491
- onHoverEnd,
492
- });
493
- return (
494
- <div
495
- ref={ref}
496
- responders={
497
- <HoverResponder delayHoverStart={500} delayHoverEnd={100} />
498
- }
499
- />
500
- );
501
- };
502
- ReactDOM.render(<Component />, container);
503
-
504
- ref.current.dispatchEvent(createEvent('pointerover'));
505
- ref.current.dispatchEvent(createEvent('pointerout'));
506
- jest.runAllTimers();
507
- expect(onHoverEnd).not.toBeCalled();
508
- });
509
- });
311
});
312
313
describe('onHoverMove', () => {