diff --git a/frontend/src/metabase/components/MetadataInfo/ColumnInfoIcon/ColumnInfoIcon.tsx b/frontend/src/metabase/components/MetadataInfo/ColumnInfoIcon/ColumnInfoIcon.tsx index b57c706cdcd22e610b3be9ee4f7bd2377139cb74..8a0abea8c126d36fc6522e22b5981d9a33955286 100644 --- a/frontend/src/metabase/components/MetadataInfo/ColumnInfoIcon/ColumnInfoIcon.tsx +++ b/frontend/src/metabase/components/MetadataInfo/ColumnInfoIcon/ColumnInfoIcon.tsx @@ -27,7 +27,6 @@ type QueryColumnInfoIconProps = QueryColumnInfoPopoverProps & { export function QueryColumnInfoIcon({ className, - delay, size, icon, color, @@ -40,7 +39,7 @@ export function QueryColumnInfoIcon({ return ( <> - <QueryColumnInfoPopover {...props} delay={delay}> + <QueryColumnInfoPopover {...props}> <span aria-label={t`More info`}> <PopoverDefaultIcon className={className} @@ -70,7 +69,6 @@ type TableColumnInfoIconProps = TableColumnInfoPopoverProps & { export function TableColumnInfoIcon({ className, - delay, field, icon, size, @@ -78,7 +76,7 @@ export function TableColumnInfoIcon({ ...props }: TableColumnInfoIconProps) { return ( - <TableColumnInfoPopover {...props} field={field} delay={delay}> + <TableColumnInfoPopover {...props} field={field}> <span aria-label={t`More info`}> <PopoverDefaultIcon className={className} diff --git a/frontend/src/metabase/components/MetadataInfo/ColumnInfoIcon/ColumnInfoIcon.unit.spec.tsx b/frontend/src/metabase/components/MetadataInfo/ColumnInfoIcon/ColumnInfoIcon.unit.spec.tsx index 66ce7b14b820fd5b7cf0f941fb1167cfab36d6e5..5733816b3bc04d6028953ad02577782cd57bac70 100644 --- a/frontend/src/metabase/components/MetadataInfo/ColumnInfoIcon/ColumnInfoIcon.unit.spec.tsx +++ b/frontend/src/metabase/components/MetadataInfo/ColumnInfoIcon/ColumnInfoIcon.unit.spec.tsx @@ -1,4 +1,4 @@ -import { fireEvent, render, screen } from "__support__/ui"; +import { fireEvent, render, screen, waitFor } from "__support__/ui"; import * as Lib from "metabase-lib"; import { columnFinder, createQuery } from "metabase-lib/test-helpers"; @@ -26,6 +26,13 @@ describe("QueryColumnInfoIcon", () => { fireEvent.mouseEnter(icon); - expect(await screen.findByText("Category")).toBeInTheDocument(); + await waitFor( + () => { + expect(screen.getByText("Category")).toBeInTheDocument(); + }, + { + timeout: 1200, + }, + ); }); }); diff --git a/frontend/src/metabase/components/MetadataInfo/ColumnInfoPopover/ColumnInfoPopover.tsx b/frontend/src/metabase/components/MetadataInfo/ColumnInfoPopover/ColumnInfoPopover.tsx index ed7531fec35550fe973b08aea3ed0e525ad87db8..560ed4690a32c360f87e9bc6970c28747b8a2bca 100644 --- a/frontend/src/metabase/components/MetadataInfo/ColumnInfoPopover/ColumnInfoPopover.tsx +++ b/frontend/src/metabase/components/MetadataInfo/ColumnInfoPopover/ColumnInfoPopover.tsx @@ -8,16 +8,16 @@ export type QueryColumnInfoPopoverProps = QueryColumnInfoProps & export function QueryColumnInfoPopover({ position, - delay, disabled, children, + openDelay, ...rest }: QueryColumnInfoPopoverProps) { return ( <Popover position={position} - delay={delay} disabled={disabled} + openDelay={openDelay} content={<QueryColumnInfo {...rest} />} > {children} @@ -30,16 +30,16 @@ export type TableColumnInfoPopoverProps = TableColumnInfoProps & export function TableColumnInfoPopover({ position, - delay, disabled, + openDelay, children, ...rest }: TableColumnInfoPopoverProps) { return ( <Popover position={position} - delay={delay} disabled={disabled} + openDelay={openDelay} content={<TableColumnInfo {...rest} />} > {children} diff --git a/frontend/src/metabase/components/MetadataInfo/Popover/Popover.styled.tsx b/frontend/src/metabase/components/MetadataInfo/Popover/Popover.styled.tsx index 1775801ba7ce2c3ec1ad4638c3fff8cea788d414..d68c6132311da1ef329579e8bbf961f65e847f0e 100644 --- a/frontend/src/metabase/components/MetadataInfo/Popover/Popover.styled.tsx +++ b/frontend/src/metabase/components/MetadataInfo/Popover/Popover.styled.tsx @@ -15,6 +15,6 @@ export const HackyInvisibleTargetFiller = styled.div` position: absolute; width: 100%; top: -10px; - min-height: 5px; + min-height: 10px; z-index: -1; `; diff --git a/frontend/src/metabase/components/MetadataInfo/Popover/Popover.tsx b/frontend/src/metabase/components/MetadataInfo/Popover/Popover.tsx index 3e09656bfe21f370f920b0f80f24419640925a68..5b06c738901633fcc51b54f85e7a55a5bc8579c1 100644 --- a/frontend/src/metabase/components/MetadataInfo/Popover/Popover.tsx +++ b/frontend/src/metabase/components/MetadataInfo/Popover/Popover.tsx @@ -5,8 +5,22 @@ import useSequencedContentCloseHandler from "metabase/hooks/use-sequenced-conten import type { HoverCardProps } from "metabase/ui"; import { HoverCard, useDelayGroup } from "metabase/ui"; -export const POPOVER_DELAY: [number, number] = [250, 150]; -export const POPOVER_TRANSITION_DURATION = 150; +const POPOVER_TRANSITION_DURATION = 150; + +// Initially, the user will have to hover for this long to open the popover +const POPOVER_SLOW_OPEN_DELAY = 250; + +// When an item in the same delay group is already open, we want to open the +// popover immediately, without waiting for the user to hover for POPOVER_SLOW_OPEN_DELAY. +// This way the user can move the cursor between hover targets and get feedback immediately. +// +// When opening fast, we still delay a little bit to avoid a flickering popover +// when the target is being clicked. +const POPOVER_FAST_OPEN_DELAY = 150; + +// When switching to another hover target in the same delay group, +// we don't close immediately but delay by a short amount to avoid flicker. +const POPOVER_CLOSE_DELAY = POPOVER_FAST_OPEN_DELAY + 30; import { Dropdown, @@ -14,24 +28,20 @@ import { WidthBound, } from "./Popover.styled"; -// When switching to another hover target in the same delay group, -// we don't close immediately but delay by a short amount to avoid flicker. -export const POPOVER_CLOSE_DELAY = 20; - export type PopoverProps = Pick< HoverCardProps, "children" | "position" | "disabled" > & { - delay?: [number, number]; width?: number; content: ReactNode; + openDelay?: number; }; export function Popover({ position = "bottom-start", disabled, - delay = POPOVER_DELAY, content, + openDelay = POPOVER_SLOW_OPEN_DELAY, width, children, }: PopoverProps) { @@ -57,8 +67,8 @@ export function Popover({ <HoverCard position={position} disabled={disabled} - openDelay={group.shouldDelay ? delay[0] : 0} - closeDelay={group.shouldDelay ? delay[1] : POPOVER_CLOSE_DELAY} + openDelay={group.shouldDelay ? openDelay : POPOVER_FAST_OPEN_DELAY} + closeDelay={POPOVER_CLOSE_DELAY} onOpen={handleOpen} onClose={handleClose} transitionProps={{ diff --git a/frontend/src/metabase/components/MetadataInfo/TableInfoIcon/TableInfoIcon.tsx b/frontend/src/metabase/components/MetadataInfo/TableInfoIcon/TableInfoIcon.tsx index 7b0d2889f01f5decf23a4f4121eb1f0eb5f8b221..a59751ebef24f76388bf9de3c008375d4541811b 100644 --- a/frontend/src/metabase/components/MetadataInfo/TableInfoIcon/TableInfoIcon.tsx +++ b/frontend/src/metabase/components/MetadataInfo/TableInfoIcon/TableInfoIcon.tsx @@ -19,14 +19,13 @@ type TableInfoIconProps = TableInfoPopoverProps & { export function TableInfoIcon({ className, - delay, table, size, icon = "table", ...props }: TableInfoIconProps) { return ( - <TableInfoPopover {...props} table={table} delay={delay}> + <TableInfoPopover {...props} table={table}> <span aria-label={t`More info`}> <PopoverDefaultIcon name={icon} className={className} size={size} /> <PopoverHoverTarget diff --git a/frontend/src/metabase/components/MetadataInfo/TableInfoPopover/TableInfoPopover.tsx b/frontend/src/metabase/components/MetadataInfo/TableInfoPopover/TableInfoPopover.tsx index 48a2f2deb77c4639395ca4850c9482fd3c0b8c7a..14ab13974c73d7c6094cee6ba8606c76f7bc8ed0 100644 --- a/frontend/src/metabase/components/MetadataInfo/TableInfoPopover/TableInfoPopover.tsx +++ b/frontend/src/metabase/components/MetadataInfo/TableInfoPopover/TableInfoPopover.tsx @@ -15,9 +15,9 @@ export type TableInfoPopoverProps = Omit<PopoverProps, "content"> & export function TableInfoPopover({ children, - delay, disabled, position, + openDelay, table, ...rest }: TableInfoPopoverProps) { @@ -30,8 +30,8 @@ export function TableInfoPopover({ return ( <Popover position={position} - delay={delay} disabled={disabled} + openDelay={openDelay} content={<TableInfo tableId={table.id} {...rest} />} > {children} diff --git a/frontend/src/metabase/visualizations/components/TableInteractive/TableInteractive.jsx b/frontend/src/metabase/visualizations/components/TableInteractive/TableInteractive.jsx index b8d8841f9d258dfb502275e9626e6637ea194131..930ed95040388e33f35f233aca42570cb549fe7c 100644 --- a/frontend/src/metabase/visualizations/components/TableInteractive/TableInteractive.jsx +++ b/frontend/src/metabase/visualizations/components/TableInteractive/TableInteractive.jsx @@ -919,6 +919,7 @@ class TableInteractive extends Component { column={query && Lib.fromLegacyColumn(query, stageIndex, column)} timezone={data.results_timezone} disabled={this.props.clicked != null || !hasMetadataPopovers} + openDelay={500} showFingerprintInfo > {renderTableHeaderWrapper(