Skip to content
This repository was archived by the owner on Nov 25, 2021. It is now read-only.

Commit a17e77f

Browse files
committed
fix: hide overlay when both hover and actions are still loading
1 parent de4f140 commit a17e77f

File tree

2 files changed

+18
-13
lines changed

2 files changed

+18
-13
lines changed

src/hoverifier.test.ts

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,8 @@ describe('Hoverifier', () => {
335335
for (const codeView of testcases) {
336336
const scheduler = new TestScheduler((a, b) => chai.assert.deepEqual(a, b))
337337

338-
const delayTime = LOADER_DELAY + 100
338+
const hoverDelayTime = 100
339+
const actionsDelayTime = 150
339340
const hover = {}
340341
const actions = ['foo', 'bar']
341342

@@ -344,8 +345,8 @@ describe('Hoverifier', () => {
344345
closeButtonClicks: new Observable<MouseEvent>(),
345346
hoverOverlayElements: of(null),
346347
hoverOverlayRerenders: EMPTY,
347-
fetchHover: createStubHoverFetcher(hover, delayTime),
348-
fetchActions: createStubActionsFetcher(actions, delayTime),
348+
fetchHover: createStubHoverFetcher(hover, LOADER_DELAY + hoverDelayTime),
349+
fetchActions: createStubActionsFetcher(actions, LOADER_DELAY + actionsDelayTime),
349350
})
350351

351352
const positionJumps = new Subject<PositionJump>()
@@ -370,24 +371,21 @@ describe('Hoverifier', () => {
370371
actionsOrError,
371372
hoverOrError,
372373
})),
373-
distinctUntilChanged((a, b) => isEqual(a, b)),
374-
// For this test, filter out the intermediate emissions where exactly one of the fetchers is
375-
// loading.
376-
filter(
377-
({ actionsOrError, hoverOrError }) =>
378-
(actionsOrError === LOADING) === (hoverOrError === LOADING)
379-
)
374+
distinctUntilChanged((a, b) => isEqual(a, b))
380375
)
381376

382377
const inputDiagram = 'a'
383378

384379
// Subtract 1ms before "b" because "a" takes up 1ms.
385-
const outputDiagram = `${LOADER_DELAY}ms a ${TOOLTIP_DISPLAY_DELAY - 1}ms b`
380+
const outputDiagram = `${LOADER_DELAY}ms ${hoverDelayTime}ms a ${actionsDelayTime -
381+
hoverDelayTime -
382+
1}ms b`
386383

387384
const outputValues: {
388385
[key: string]: Pick<HoverOverlayProps<{}, {}, string>, 'hoverOrError' | 'actionsOrError'>
389386
} = {
390-
a: { hoverOrError: LOADING, actionsOrError: LOADING }, // actions is undefined when it is loading
387+
// No hover is shown if it would just consist of LOADING.
388+
a: { hoverOrError: createHoverAttachment(hover), actionsOrError: LOADING },
391389
b: { hoverOrError: createHoverAttachment(hover), actionsOrError: actions },
392390
}
393391

src/hoverifier.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,9 +247,16 @@ interface InternalHoverifierState<C extends object, D, A> {
247247

248248
/**
249249
* Returns true if the HoverOverlay component should be rendered according to the given state.
250+
*
251+
* The primary purpose of this is to reduce UI jitter by not showing the overlay when there is nothing to show
252+
* (because there is no content, or because it is still loading).
250253
*/
251254
const shouldRenderOverlay = (state: InternalHoverifierState<{}, {}, {}>): boolean =>
252-
!(!state.hoverOverlayIsFixed && state.mouseIsMoving) && !!state.hoverOrError && !isErrorLike(state.hoverOrError)
255+
!(!state.hoverOverlayIsFixed && state.mouseIsMoving) &&
256+
((!!state.hoverOrError && state.hoverOrError !== LOADING) ||
257+
(!!state.actionsOrError &&
258+
state.actionsOrError !== LOADING &&
259+
(isErrorLike(state.actionsOrError) || state.actionsOrError.length > 0)))
253260

254261
/**
255262
* Maps internal HoverifierState to the publicly exposed HoverState

0 commit comments

Comments
 (0)