Skip to content

Commit e276a5e

Browse files
authored
[Flare] Remove delay props from Hover (#16248)
Moving working with delays into user-space.
1 parent 1912b4a commit e276a5e

File tree

3 files changed

+5
-259
lines changed

3 files changed

+5
-259
lines changed

packages/react-events/docs/Hover.md

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,6 @@ type HoverEvent = {
3737

3838
## Props
3939

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-
5040
### disabled: boolean
5141

5242
Disables all `Hover` events.
@@ -58,19 +48,15 @@ Called when the element changes hover state (i.e., after `onHoverStart` and
5848

5949
### onHoverEnd: (e: HoverEvent) => void
6050

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.
6352

6453
### onHoverMove: (e: HoverEvent) => void
6554

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.
6856

6957
### onHoverStart: (e: HoverEvent) => void
7058

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.
7460

7561
### preventDefault: boolean = true
7662

packages/react-events/src/dom/Hover.js

Lines changed: 2 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ type HoverListenerProps = {|
2424

2525
type HoverProps = {
2626
disabled: boolean,
27-
delayHoverEnd: number,
28-
delayHoverStart: number,
2927
preventDefault: boolean,
3028
};
3129

@@ -55,9 +53,6 @@ type HoverEvent = {|
5553
y: null | number,
5654
|};
5755

58-
const DEFAULT_HOVER_END_DELAY_MS = 0;
59-
const DEFAULT_HOVER_START_DELAY_MS = 0;
60-
6156
const targetEventTypes = [
6257
'pointerover',
6358
'pointermove',
@@ -136,7 +131,7 @@ function dispatchHoverStartEvents(
136131
state.hoverEndTimeout = null;
137132
}
138133

139-
const activate = () => {
134+
if (!state.isActiveHovered) {
140135
state.isActiveHovered = true;
141136
const syntheticEvent = createHoverEvent(
142137
event,
@@ -146,22 +141,6 @@ function dispatchHoverStartEvents(
146141
);
147142
context.dispatchEvent('onHoverStart', syntheticEvent, UserBlockingEvent);
148143
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-
}
165144
}
166145
}
167146

@@ -188,7 +167,7 @@ function dispatchHoverEndEvents(
188167
state.hoverStartTimeout = null;
189168
}
190169

191-
const deactivate = () => {
170+
if (state.isActiveHovered) {
192171
state.isActiveHovered = false;
193172

194173
const syntheticEvent = createHoverEvent(
@@ -202,29 +181,9 @@ function dispatchHoverEndEvents(
202181
state.hoverTarget = null;
203182
state.ignoreEmulatedMouseEvents = false;
204183
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-
}
220184
}
221185
}
222186

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-
228187
function unmountResponder(
229188
context: ReactDOMResponderContext,
230189
props: HoverProps,

packages/react-events/src/dom/__tests__/Hover-test.internal.js

Lines changed: 0 additions & 199 deletions
Original file line numberDiff line numberDiff line change
@@ -167,97 +167,6 @@ describe('Hover event responder', () => {
167167
);
168168
expect(onHoverStart).not.toBeCalled();
169169
});
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-
});
261170
});
262171

263172
describe('onHoverChange', () => {
@@ -399,114 +308,6 @@ describe('Hover event responder', () => {
399308
ref.current.dispatchEvent(createEvent('mouseout'));
400309
expect(onHoverEnd).not.toBeCalled();
401310
});
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-
});
510311
});
511312

512313
describe('onHoverMove', () => {

0 commit comments

Comments
 (0)