mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Chore: remove react-popper-tooltip in favour of @floating-ui/react (#79465)
* use floating-ui instead of react-popper-tooltip in Tooltip * remove useTheme2 usage * remove escape handling logic in favour of useDismiss * don't need this useEffect anymore * convert Toggletip to use floating-ui * use explicit version * convert OperationInfoButton to use Toggletip * convert nestedFolderPicker to use floating-ui * convert Dropdown to use floating-ui and remove react-popper-tooltip * fix Modal/Tooltip tests * revert to old toggletip behaviour * revert OperationInfoButton to not use Toggletip * add mock for requestAnimationFrame * remove requestAnimationFrame mock * remove fakeTimers where they're not used * use floating-ui in ButtonSelect * Fix filters unit tests * only attach description if label is different * use 'fixed' strategy for Toggletip * use stroke and strokeWidth * set move: false to only show the tooltip if a hover event occurs * update type for onClose
This commit is contained in:
@@ -57,7 +57,7 @@ export function AppChromeMenu({}: Props) {
|
||||
classNames={animationStyles.overlay}
|
||||
timeout={{ enter: animationSpeed, exit: 0 }}
|
||||
>
|
||||
<FocusScope contain autoFocus>
|
||||
<FocusScope contain autoFocus restoreFocus>
|
||||
<MegaMenu className={styles.menu} onClose={onClose} ref={ref} {...overlayProps} {...dialogProps} />
|
||||
</FocusScope>
|
||||
</CSSTransition>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { autoUpdate, flip, useClick, useDismiss, useFloating, useInteractions } from '@floating-ui/react';
|
||||
import React, { useCallback, useId, useMemo, useState } from 'react';
|
||||
import { usePopperTooltip } from 'react-popper-tooltip';
|
||||
import { useAsync } from 'react-use';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
@@ -85,13 +85,19 @@ export function NestedFolderPicker({
|
||||
const rootCollection = useSelector(rootItemsSelector);
|
||||
const childrenCollections = useSelector(childrenByParentUIDSelector);
|
||||
|
||||
const { getTooltipProps, setTooltipRef, setTriggerRef, visible, triggerRef } = usePopperTooltip({
|
||||
visible: overlayOpen,
|
||||
// the order of middleware is important!
|
||||
const middleware = [
|
||||
flip({
|
||||
// see https://floating-ui.com/docs/flip#combining-with-shift
|
||||
crossAxis: false,
|
||||
boundary: document.body,
|
||||
}),
|
||||
];
|
||||
|
||||
const { context, refs, floatingStyles, elements } = useFloating({
|
||||
open: overlayOpen,
|
||||
placement: 'bottom',
|
||||
interactive: true,
|
||||
offset: [0, 0],
|
||||
trigger: 'click',
|
||||
onVisibleChange: (value: boolean) => {
|
||||
onOpenChange: (value) => {
|
||||
// ensure state is clean on opening the overlay
|
||||
if (value) {
|
||||
setSearch('');
|
||||
@@ -99,8 +105,15 @@ export function NestedFolderPicker({
|
||||
}
|
||||
setOverlayOpen(value);
|
||||
},
|
||||
middleware,
|
||||
whileElementsMounted: autoUpdate,
|
||||
});
|
||||
|
||||
const click = useClick(context);
|
||||
const dismiss = useDismiss(context);
|
||||
|
||||
const { getReferenceProps, getFloatingProps } = useInteractions([dismiss, click]);
|
||||
|
||||
const handleFolderExpand = useCallback(
|
||||
async (uid: string, newOpenState: boolean) => {
|
||||
setFolderOpenState((old) => ({ ...old, [uid]: newOpenState }));
|
||||
@@ -209,7 +222,7 @@ export function NestedFolderPicker({
|
||||
handleFolderExpand,
|
||||
idPrefix: overlayId,
|
||||
search,
|
||||
visible,
|
||||
visible: overlayOpen,
|
||||
});
|
||||
|
||||
let label = selectedFolder.data?.title;
|
||||
@@ -217,14 +230,14 @@ export function NestedFolderPicker({
|
||||
label = 'Dashboards';
|
||||
}
|
||||
|
||||
if (!visible) {
|
||||
if (!overlayOpen) {
|
||||
return (
|
||||
<Trigger
|
||||
label={label}
|
||||
invalid={invalid}
|
||||
isLoading={selectedFolder.isLoading}
|
||||
autoFocus={autoFocusButton}
|
||||
ref={setTriggerRef}
|
||||
ref={refs.setReference}
|
||||
aria-label={
|
||||
label
|
||||
? t('browse-dashboards.folder-picker.accessible-label', 'Select folder: {{ label }} currently selected', {
|
||||
@@ -232,6 +245,7 @@ export function NestedFolderPicker({
|
||||
})
|
||||
: undefined
|
||||
}
|
||||
{...getReferenceProps()}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -239,14 +253,13 @@ export function NestedFolderPicker({
|
||||
return (
|
||||
<>
|
||||
<Input
|
||||
ref={setTriggerRef}
|
||||
ref={refs.setReference}
|
||||
autoFocus
|
||||
prefix={label ? <Icon name="folder" /> : null}
|
||||
placeholder={label ?? t('browse-dashboards.folder-picker.search-placeholder', 'Search folders')}
|
||||
value={search}
|
||||
invalid={invalid}
|
||||
className={styles.search}
|
||||
onKeyDown={handleKeyDown}
|
||||
onChange={(e) => setSearch(e.currentTarget.value)}
|
||||
aria-autocomplete="list"
|
||||
aria-expanded
|
||||
@@ -256,16 +269,18 @@ export function NestedFolderPicker({
|
||||
aria-activedescendant={getDOMId(overlayId, flatTree[focusedItemIndex]?.item.uid)}
|
||||
role="combobox"
|
||||
suffix={<Icon name="search" />}
|
||||
{...getReferenceProps()}
|
||||
onKeyDown={handleKeyDown}
|
||||
/>
|
||||
<fieldset
|
||||
ref={setTooltipRef}
|
||||
ref={refs.setFloating}
|
||||
id={overlayId}
|
||||
{...getTooltipProps({
|
||||
className: styles.tableWrapper,
|
||||
style: {
|
||||
width: triggerRef?.clientWidth,
|
||||
},
|
||||
})}
|
||||
className={styles.tableWrapper}
|
||||
style={{
|
||||
...floatingStyles,
|
||||
width: elements.domReference?.clientWidth,
|
||||
}}
|
||||
{...getFloatingProps()}
|
||||
>
|
||||
{error ? (
|
||||
<Alert
|
||||
|
||||
Reference in New Issue
Block a user