From b559fee904a96cd36ede6f87d28a2d4ac8ebfe7b Mon Sep 17 00:00:00 2001 From: Marius Andra Date: Tue, 1 Sep 2020 15:51:53 +0200 Subject: [PATCH] WIP: have the element info window follow the mouse (#1472) --- frontend/src/toolbar/elements/InfoWindow.tsx | 27 +++++++++++--- .../src/toolbar/elements/elementsLogic.ts | 37 +++++++++++++++++-- 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/frontend/src/toolbar/elements/InfoWindow.tsx b/frontend/src/toolbar/elements/InfoWindow.tsx index 5bf0392978f9d..222a483233b33 100644 --- a/frontend/src/toolbar/elements/InfoWindow.tsx +++ b/frontend/src/toolbar/elements/InfoWindow.tsx @@ -5,7 +5,14 @@ import { elementsLogic } from '~/toolbar/elements/elementsLogic' import { ElementInfo } from '~/toolbar/elements/ElementInfo' export function InfoWindow(): JSX.Element | null { - const { hoverElement, hoverElementMeta, selectedElement, selectedElementMeta } = useValues(elementsLogic) + const { + hoverElement, + hoverElementMeta, + selectedElement, + selectedElementMeta, + mouseCoordinates, + selectedElementMouseCoordinates, + } = useValues(elementsLogic) const { setSelectedElement } = useActions(elementsLogic) // use rectUpdateCounter to reload component when it changes, but discard the output @@ -27,7 +34,14 @@ export function InfoWindow(): JSX.Element | null { const windowWidth = Math.min(document.documentElement.clientWidth, window.innerWidth) const windowHeight = Math.min(document.documentElement.clientHeight, window.innerHeight) - let left = rect.left + window.pageXOffset + (rect.width > 300 ? (rect.width - 300) / 2 : 0) + const mouseX = + pointerEvents && selectedElementMouseCoordinates ? selectedElementMouseCoordinates.x : mouseCoordinates.x + const mouseY = + pointerEvents && selectedElementMouseCoordinates ? selectedElementMouseCoordinates.y : mouseCoordinates.y + + let left = + window.pageXOffset + + (typeof mouseX !== 'undefined' ? mouseX + 5 : rect.left + (rect.width > 300 ? (rect.width - 300) / 2 : 0)) let width = 300 if (left + width > windowWidth - 10) { left -= left + width - (windowWidth - 10) @@ -37,17 +51,20 @@ export function InfoWindow(): JSX.Element | null { } } - let top: number | undefined = Math.max(window.pageYOffset + 16, rect.top + rect.height + 10 + window.pageYOffset) + let top: number | undefined = Math.max( + window.pageYOffset + 16, + (typeof mouseY !== 'undefined' ? mouseY + 5 : rect.top + rect.height + 10) + window.pageYOffset + ) let bottom: number | undefined const minHeight: number | undefined = 50 let maxHeight: number | undefined - const spaceAbove = Math.max(minHeight, rect.top - 20) + const spaceAbove = Math.max(minHeight, (typeof mouseY !== 'undefined' ? mouseY : rect.top) - 20) const spaceBelow = Math.max(minHeight, windowHeight - top + window.pageYOffset - 10) if (spaceAbove > spaceBelow) { top = undefined - bottom = windowHeight - rect.top + 10 - window.pageYOffset + bottom = windowHeight - (typeof mouseY !== 'undefined' ? mouseY - 5 : rect.top - 10) - window.pageYOffset maxHeight = spaceAbove } else { maxHeight = spaceBelow diff --git a/frontend/src/toolbar/elements/elementsLogic.ts b/frontend/src/toolbar/elements/elementsLogic.ts index 1673f8a40d71f..c5155c0cb0714 100644 --- a/frontend/src/toolbar/elements/elementsLogic.ts +++ b/frontend/src/toolbar/elements/elementsLogic.ts @@ -38,7 +38,12 @@ export const elementsLogic = kea< updateRects: true, setHoverElement: (element: HTMLElement | null) => ({ element }), setHighlightElement: (element: HTMLElement | null) => ({ element }), - setSelectedElement: (element: HTMLElement | null) => ({ element }), + setSelectedElement: (element: HTMLElement | null, x?: number, y?: number) => ({ + element, + x, + y, + }), + setMouseCoordinates: (x: number, y: number) => ({ x, y }), }, reducers: () => ({ @@ -88,6 +93,18 @@ export const elementsLogic = kea< [actionsTabLogic.actionTypes.selectAction]: () => null, }, ], + selectedElementMouseCoordinates: [ + null as null | { x: number; y: number }, + { + setSelectedElement: (_, { x, y }) => + typeof x !== 'undefined' && typeof y !== 'undefined' ? { x, y } : null, + disableInspect: () => null, + createAction: () => null, + [toolbarTabLogic.actionTypes.setTab]: () => null, + [heatmapLogic.actionTypes.disableHeatmap]: () => null, + [actionsTabLogic.actionTypes.selectAction]: () => null, + }, + ], enabledLast: [ null as null | 'inspect' | 'heatmap', { @@ -96,6 +113,12 @@ export const elementsLogic = kea< [heatmapLogic.actionTypes.enableHeatmap]: () => 'heatmap', }, ], + mouseCoordinates: [ + { x: undefined, y: undefined } as { x: number | undefined; y: number | undefined }, + { + setMouseCoordinates: (_, { x, y }) => ({ x, y }), + }, + ], }), selectors: { @@ -372,20 +395,28 @@ export const elementsLogic = kea< return } } + cache.onMouseMove = (e: MouseEvent) => { + const { x, y } = values.mouseCoordinates + if (x !== e.clientX || y !== e.clientY) { + actions.setMouseCoordinates(e.clientX, e.clientY) + } + } window.addEventListener('click', cache.onClick) window.addEventListener('resize', cache.onScrollResize) window.addEventListener('keydown', cache.onKeyDown) + window.addEventListener('mousemove', cache.onMouseMove) window.document.addEventListener('scroll', cache.onScrollResize, true) }, beforeUnmount: () => { window.removeEventListener('click', cache.onClick) window.removeEventListener('resize', cache.onScrollResize) window.removeEventListener('keydown', cache.onKeyDown) + window.removeEventListener('mousemove', cache.onMouseMove) window.document.removeEventListener('scroll', cache.onScrollResize, true) }, }), - listeners: ({ actions }) => ({ + listeners: ({ actions, values }) => ({ enableInspect: () => { actionsLogic.actions.getActions() }, @@ -401,7 +432,7 @@ export const elementsLogic = kea< actionsTabLogic.actions.inspectElementSelected(element, actionsTabLogic.values.inspectingElement) } } else { - actions.setSelectedElement(element) + actions.setSelectedElement(element, values.mouseCoordinates.x, values.mouseCoordinates.y) } }, createAction: ({ element }) => {