Chore: replace react-popper with floating-ui in ExemplarMarker (#83694)

* replace react-popper with floating-ui in ExemplarMarker

* fix e2e test

* floating-ui uses mousemove
This commit is contained in:
Ashley Harrison 2024-03-01 14:54:39 +00:00 committed by GitHub
parent 10a55560df
commit 086d47d83c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 50 additions and 60 deletions

View File

@ -69,7 +69,7 @@ describe('Exemplars', () => {
cy.get(`[data-testid="time-series-zoom-to-data"]`).click(); cy.get(`[data-testid="time-series-zoom-to-data"]`).click();
e2e.components.DataSource.Prometheus.exemplarMarker().first().trigger('mouseover'); e2e.components.DataSource.Prometheus.exemplarMarker().first().trigger('mousemove');
cy.contains('Query with gdev-tempo').click(); cy.contains('Query with gdev-tempo').click();
e2e.components.TraceViewer.spanBar().should('have.length', 11); e2e.components.TraceViewer.spanBar().should('have.length', 11);
}); });

View File

@ -376,7 +376,6 @@
"react-inlinesvg": "3.0.2", "react-inlinesvg": "3.0.2",
"react-loading-skeleton": "3.4.0", "react-loading-skeleton": "3.4.0",
"react-moveable": "0.56.0", "react-moveable": "0.56.0",
"react-popper": "2.3.0",
"react-redux": "8.1.3", "react-redux": "8.1.3",
"react-resizable": "3.0.5", "react-resizable": "3.0.5",
"react-responsive-carousel": "^3.2.23", "react-responsive-carousel": "^3.2.23",

View File

@ -93,7 +93,6 @@
"react-i18next": "^12.0.0", "react-i18next": "^12.0.0",
"react-inlinesvg": "3.0.2", "react-inlinesvg": "3.0.2",
"react-loading-skeleton": "3.4.0", "react-loading-skeleton": "3.4.0",
"react-popper": "2.3.0",
"react-router-dom": "5.3.3", "react-router-dom": "5.3.3",
"react-select": "5.8.0", "react-select": "5.8.0",
"react-table": "7.8.0", "react-table": "7.8.0",

View File

@ -1,6 +1,15 @@
import { css, cx } from '@emotion/css'; import { css, cx } from '@emotion/css';
import React, { CSSProperties, useCallback, useEffect, useRef, useState } from 'react'; import {
import { usePopper } from 'react-popper'; autoUpdate,
flip,
safePolygon,
shift,
useDismiss,
useFloating,
useHover,
useInteractions,
} from '@floating-ui/react';
import React, { CSSProperties, useCallback, useEffect, useState } from 'react';
import { import {
DataFrame, DataFrame,
@ -44,25 +53,34 @@ export const ExemplarMarker = ({
const styles = useStyles2(getExemplarMarkerStyles); const styles = useStyles2(getExemplarMarkerStyles);
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const [isLocked, setIsLocked] = useState(false); const [isLocked, setIsLocked] = useState(false);
const [markerElement, setMarkerElement] = React.useState<HTMLDivElement | null>(null);
const [popperElement, setPopperElement] = React.useState<HTMLDivElement | null>(null); // the order of middleware is important!
const { styles: popperStyles, attributes } = usePopper(markerElement, popperElement, { const middleware = [
modifiers: [ flip({
{ fallbackAxisSideDirection: 'end',
name: 'preventOverflow', // see https://floating-ui.com/docs/flip#combining-with-shift
options: { crossAxis: false,
altAxis: true, boundary: document.body,
}, }),
}, shift(),
{ ];
name: 'flip',
options: { const { context, refs, floatingStyles } = useFloating({
fallbackPlacements: ['top', 'left-start'], open: isOpen,
}, placement: 'bottom',
}, onOpenChange: setIsOpen,
], middleware,
whileElementsMounted: autoUpdate,
strategy: 'fixed',
}); });
const popoverRenderTimeout = useRef<NodeJS.Timeout>();
const dismiss = useDismiss(context);
const hover = useHover(context, {
handleClose: safePolygon(),
enabled: clickedExemplarFieldIndex === undefined,
});
const { getReferenceProps, getFloatingProps } = useInteractions([dismiss, hover]);
useEffect(() => { useEffect(() => {
if ( if (
@ -107,25 +125,10 @@ export const ExemplarMarker = ({
return symbols[dataFrameFieldIndex.frameIndex % symbols.length]; return symbols[dataFrameFieldIndex.frameIndex % symbols.length];
}; };
const onMouseEnter = useCallback(() => {
if (clickedExemplarFieldIndex === undefined) {
if (popoverRenderTimeout.current) {
clearTimeout(popoverRenderTimeout.current);
}
setIsOpen(true);
}
}, [setIsOpen, clickedExemplarFieldIndex]);
const lockExemplarModal = () => { const lockExemplarModal = () => {
setIsLocked(true); setIsLocked(true);
}; };
const onMouseLeave = useCallback(() => {
popoverRenderTimeout.current = setTimeout(() => {
setIsOpen(false);
}, 150);
}, [setIsOpen]);
const renderMarker = useCallback(() => { const renderMarker = useCallback(() => {
//Put fields with links on the top //Put fields with links on the top
const fieldsWithLinks = const fieldsWithLinks =
@ -220,28 +223,20 @@ export const ExemplarMarker = ({
}; };
return ( return (
<div <div className={styles.tooltip} ref={refs.setFloating} style={floatingStyles} {...getFloatingProps()}>
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
className={styles.tooltip}
ref={setPopperElement}
style={popperStyles.popper}
{...attributes.popper}
>
{getExemplarMarkerContent()} {getExemplarMarkerContent()}
</div> </div>
); );
}, [ }, [
attributes.popper,
dataFrame.fields, dataFrame.fields,
dataFrameFieldIndex, dataFrameFieldIndex,
onMouseEnter,
onMouseLeave,
popperStyles.popper,
styles, styles,
timeZone, timeZone,
isLocked, isLocked,
setClickedExemplarFieldIndex, setClickedExemplarFieldIndex,
floatingStyles,
getFloatingProps,
refs.setFloating,
]); ]);
const seriesColor = config const seriesColor = config
@ -256,19 +251,18 @@ export const ExemplarMarker = ({
return ( return (
<> <>
<div <div
ref={setMarkerElement} ref={refs.setReference}
className={styles.markerWrapper}
data-testid={selectors.components.DataSource.Prometheus.exemplarMarker}
role="button"
tabIndex={0}
{...getReferenceProps()}
onClick={onExemplarClick} onClick={onExemplarClick}
onKeyDown={(e: React.KeyboardEvent) => { onKeyDown={(e: React.KeyboardEvent) => {
if (e.key === 'Enter') { if (e.key === 'Enter') {
onExemplarClick(); onExemplarClick();
} }
}} }}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
className={styles.markerWrapper}
data-testid={selectors.components.DataSource.Prometheus.exemplarMarker}
role="button"
tabIndex={0}
> >
<svg <svg
viewBox="0 0 7 7" viewBox="0 0 7 7"

View File

@ -4265,7 +4265,6 @@ __metadata:
react-i18next: "npm:^12.0.0" react-i18next: "npm:^12.0.0"
react-inlinesvg: "npm:3.0.2" react-inlinesvg: "npm:3.0.2"
react-loading-skeleton: "npm:3.4.0" react-loading-skeleton: "npm:3.4.0"
react-popper: "npm:2.3.0"
react-router-dom: "npm:5.3.3" react-router-dom: "npm:5.3.3"
react-select: "npm:5.8.0" react-select: "npm:5.8.0"
react-select-event: "npm:^5.1.0" react-select-event: "npm:^5.1.0"
@ -18595,7 +18594,6 @@ __metadata:
react-inlinesvg: "npm:3.0.2" react-inlinesvg: "npm:3.0.2"
react-loading-skeleton: "npm:3.4.0" react-loading-skeleton: "npm:3.4.0"
react-moveable: "npm:0.56.0" react-moveable: "npm:0.56.0"
react-popper: "npm:2.3.0"
react-redux: "npm:8.1.3" react-redux: "npm:8.1.3"
react-refresh: "npm:0.14.0" react-refresh: "npm:0.14.0"
react-resizable: "npm:3.0.5" react-resizable: "npm:3.0.5"
@ -26382,7 +26380,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"react-popper@npm:2.3.0, react-popper@npm:^2.3.0": "react-popper@npm:^2.3.0":
version: 2.3.0 version: 2.3.0
resolution: "react-popper@npm:2.3.0" resolution: "react-popper@npm:2.3.0"
dependencies: dependencies: