From 846e180bd5ebef89d10e12531e69978c7cb3278b Mon Sep 17 00:00:00 2001 From: wes337 Date: Sat, 19 Feb 2022 10:50:17 +0200 Subject: [PATCH 1/7] [@mantine/core] Select: only use open/close callback when value changes --- src/mantine-core/src/components/Select/Select.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mantine-core/src/components/Select/Select.tsx b/src/mantine-core/src/components/Select/Select.tsx index 9f646fefba3..84a4cd8dcf2 100644 --- a/src/mantine-core/src/components/Select/Select.tsx +++ b/src/mantine-core/src/components/Select/Select.tsx @@ -214,6 +214,10 @@ export const Select = forwardRef( const isDeselectable = allowDeselect === undefined ? clearable : allowDeselect; const setDropdownOpened = (opened: boolean) => { + if (dropdownOpened === opened) { + return; + } + _setDropdownOpened(opened); const handler = opened ? onDropdownOpen : onDropdownClose; typeof handler === 'function' && handler(); From 9e8045f8e430043f8540a86ef65eba31b9f7e47d Mon Sep 17 00:00:00 2001 From: Wesley Moses Date: Sat, 19 Feb 2022 11:43:41 +0200 Subject: [PATCH 2/7] [@mantine/core] Select: do not use early return --- src/mantine-core/src/components/Select/Select.tsx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/mantine-core/src/components/Select/Select.tsx b/src/mantine-core/src/components/Select/Select.tsx index 84a4cd8dcf2..29e0b1ca717 100644 --- a/src/mantine-core/src/components/Select/Select.tsx +++ b/src/mantine-core/src/components/Select/Select.tsx @@ -214,13 +214,11 @@ export const Select = forwardRef( const isDeselectable = allowDeselect === undefined ? clearable : allowDeselect; const setDropdownOpened = (opened: boolean) => { - if (dropdownOpened === opened) { - return; + if (dropdownOpened !== opened) { + _setDropdownOpened(opened); + const handler = opened ? onDropdownOpen : onDropdownClose; + typeof handler === 'function' && handler(); } - - _setDropdownOpened(opened); - const handler = opened ? onDropdownOpen : onDropdownClose; - typeof handler === 'function' && handler(); }; const isCreatable = creatable && typeof getCreateLabel === 'function'; From b489abdf1fd7a5fb194a39bc065f4c0d4cbca489 Mon Sep 17 00:00:00 2001 From: wes337 Date: Sun, 10 Apr 2022 10:47:53 +0300 Subject: [PATCH 3/7] [@mantine/core] Tooltip: floating tooltip positioned inside component instead of popper --- .../src/components/Popper/Popper.tsx | 5 --- .../FloatingTooltip/FloatingTooltip.tsx | 31 ++++++++++++---- .../core/Tooltip/Tooltip.demo.positions.tsx | 36 +++++++------------ 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/mantine-core/src/components/Popper/Popper.tsx b/src/mantine-core/src/components/Popper/Popper.tsx index 52e9aea2a5b..e2996324675 100644 --- a/src/mantine-core/src/components/Popper/Popper.tsx +++ b/src/mantine-core/src/components/Popper/Popper.tsx @@ -41,9 +41,6 @@ export interface SharedPopperProps { /** Mount/unmount transition timing function, defaults to theme.transitionTimingFunction */ transitionTimingFunction?: string; - - /** Exact coordinates where to position popper on page */ - coordinates?: { x: number; y: number }; } export interface PopperProps extends SharedPopperProps { @@ -128,7 +125,6 @@ export function Popper({ modifiers = [], onTransitionEnd, withinPortal = true, - coordinates, }: PopperProps) { const padding = withArrow ? gutter + arrowSize : gutter; const { classes, cx, theme } = useStyles({ arrowSize, arrowDistance }, { name: 'Popper' }); @@ -175,7 +171,6 @@ export function Popper({ style={{ ...styles.popper, pointerEvents: 'none', - ...(coordinates && { top: coordinates.y || 0, left: coordinates.x || 0 }), }} {...attributes.popper} > diff --git a/src/mantine-core/src/components/Tooltip/FloatingTooltip/FloatingTooltip.tsx b/src/mantine-core/src/components/Tooltip/FloatingTooltip/FloatingTooltip.tsx index 245e555b98b..c4621db39d1 100644 --- a/src/mantine-core/src/components/Tooltip/FloatingTooltip/FloatingTooltip.tsx +++ b/src/mantine-core/src/components/Tooltip/FloatingTooltip/FloatingTooltip.tsx @@ -121,19 +121,36 @@ export const FloatingTooltip = forwardRef( // There's no way to get the exact size of the // cursor using JS, however most OS's use 32x32 const estimatedCursorSize = 32; - const tooltipWidth = _tooltipRef.current?.offsetWidth || 0; + const tooltipWidth = + typeof width === 'number' ? width : _tooltipRef.current?.offsetWidth || 0; + const tooltipHeight = _tooltipRef.current?.offsetHeight || 0; switch (position) { case 'top': - return { x: x - tooltipWidth / 2, y: y - estimatedCursorSize }; + return { + left: x - tooltipWidth / 2, + top: y, + }; case 'left': - return { x: x - estimatedCursorSize / 2 - tooltipWidth, y }; + return { + left: x - tooltipWidth - estimatedCursorSize / 2, + top: y + estimatedCursorSize, + }; case 'right': - return { x: x + estimatedCursorSize / 2, y }; + return { + left: x + estimatedCursorSize / 2, + top: y + estimatedCursorSize, + }; case 'bottom': - return { x: x - tooltipWidth / 2, y: y + estimatedCursorSize }; + return { + left: x - tooltipWidth / 2, + top: y + tooltipHeight + estimatedCursorSize, + }; default: - return { x: x || 0, y: y || 0 }; + return { + left: x || 0, + top: y || 0, + }; } }, [x, y]); @@ -196,7 +213,6 @@ export const FloatingTooltip = forwardRef( zIndex={zIndex} forceUpdateDependencies={[color, radius, ...positionDependencies]} withinPortal={withinPortal} - coordinates={coordinates} > ( sx={{ whiteSpace: wrapLines ? 'normal' : 'nowrap', width, + ...coordinates, }} > {label} diff --git a/src/mantine-demos/src/demos/core/Tooltip/Tooltip.demo.positions.tsx b/src/mantine-demos/src/demos/core/Tooltip/Tooltip.demo.positions.tsx index 2a637cb4dd2..ee5541a2866 100644 --- a/src/mantine-demos/src/demos/core/Tooltip/Tooltip.demo.positions.tsx +++ b/src/mantine-demos/src/demos/core/Tooltip/Tooltip.demo.positions.tsx @@ -1,31 +1,19 @@ import React from 'react'; -import { Tooltip, Badge, Group } from '@mantine/core'; +import { FloatingTooltip, Box, Group } from '@mantine/core'; function Demo() { - const tooltips = (['top', 'right', 'bottom', 'left'] as const).map((position, index) => { - const placements = (['start', 'center', 'end'] as const).map((placement) => ( - - - {`${position}-${placement}`} - - - )); - - return ( - - {placements} + return ( +
+ + + Ok Tooltip + + + Weird Tooltip + - ); - }); - - return <>{tooltips}; +
+ ); } export const positions: MantineDemo = { From 7d3071c45af81fe5ae173a287cd8611e18356b18 Mon Sep 17 00:00:00 2001 From: wes337 Date: Sun, 10 Apr 2022 10:54:30 +0300 Subject: [PATCH 4/7] [@mantine/core] Tooltip: revert positions story back --- .../core/Tooltip/Tooltip.demo.positions.tsx | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/mantine-demos/src/demos/core/Tooltip/Tooltip.demo.positions.tsx b/src/mantine-demos/src/demos/core/Tooltip/Tooltip.demo.positions.tsx index ee5541a2866..2a637cb4dd2 100644 --- a/src/mantine-demos/src/demos/core/Tooltip/Tooltip.demo.positions.tsx +++ b/src/mantine-demos/src/demos/core/Tooltip/Tooltip.demo.positions.tsx @@ -1,19 +1,31 @@ import React from 'react'; -import { FloatingTooltip, Box, Group } from '@mantine/core'; +import { Tooltip, Badge, Group } from '@mantine/core'; function Demo() { - return ( -
- - - Ok Tooltip - - - Weird Tooltip - + const tooltips = (['top', 'right', 'bottom', 'left'] as const).map((position, index) => { + const placements = (['start', 'center', 'end'] as const).map((placement) => ( + + + {`${position}-${placement}`} + + + )); + + return ( + + {placements} -
- ); + ); + }); + + return <>{tooltips}; } export const positions: MantineDemo = { From ed511500fb7fa52c5fed8c993515cb06d52dd453 Mon Sep 17 00:00:00 2001 From: wes337 Date: Sun, 10 Apr 2022 12:31:39 +0300 Subject: [PATCH 5/7] [@mantine/core] Tooltip: remove popper from floating tooltip --- .../FloatingTooltip/FloatingTooltip.styles.ts | 3 +- .../FloatingTooltip/FloatingTooltip.tsx | 85 ++++++++++--------- 2 files changed, 47 insertions(+), 41 deletions(-) diff --git a/src/mantine-core/src/components/Tooltip/FloatingTooltip/FloatingTooltip.styles.ts b/src/mantine-core/src/components/Tooltip/FloatingTooltip/FloatingTooltip.styles.ts index eab3709e337..41c56aec291 100644 --- a/src/mantine-core/src/components/Tooltip/FloatingTooltip/FloatingTooltip.styles.ts +++ b/src/mantine-core/src/components/Tooltip/FloatingTooltip/FloatingTooltip.styles.ts @@ -19,8 +19,9 @@ export default createStyles((theme, { color, radius }: FloatingTooltipStylesPara borderRadius: theme.fn.radius(radius), padding: `${theme.spacing.xs / 2}px ${theme.spacing.xs}px`, color: theme.colorScheme === 'dark' ? theme.colors.dark[9] : theme.white, - position: 'relative', + position: 'absolute', overflow: 'hidden', textOverflow: 'ellipsis', + pointerEvents: 'none', }, })); diff --git a/src/mantine-core/src/components/Tooltip/FloatingTooltip/FloatingTooltip.tsx b/src/mantine-core/src/components/Tooltip/FloatingTooltip/FloatingTooltip.tsx index c4621db39d1..4c2437681eb 100644 --- a/src/mantine-core/src/components/Tooltip/FloatingTooltip/FloatingTooltip.tsx +++ b/src/mantine-core/src/components/Tooltip/FloatingTooltip/FloatingTooltip.tsx @@ -9,14 +9,13 @@ import { } from '@mantine/styles'; import { useMergedRef, useMouse } from '@mantine/hooks'; import { Box } from '../../Box'; -import { Popper, SharedPopperProps } from '../../Popper'; +import { MantineTransition, Transition } from '../../Transition'; import useStyles from './FloatingTooltip.styles'; export type FloatingTooltipStylesNames = ClassNames; export interface FloatingTooltipProps extends DefaultProps, - SharedPopperProps, React.ComponentPropsWithoutRef<'div'> { /** Tooltip content */ label: React.ReactNode; @@ -51,17 +50,28 @@ export interface FloatingTooltipProps /** Tooltip id to bind aria-describedby */ tooltipId?: string; - /** useEffect dependencies to force update tooltip position */ - positionDependencies?: any[]; + /** Position of the tooltip relative to the cursor */ + position?: 'top' | 'left' | 'bottom' | 'right'; - /** Whether to render the target element in a Portal */ - withinPortal?: boolean; + /** Customize mount/unmount transition */ + transition?: MantineTransition; + + /** Mount transition duration in ms */ + transitionDuration?: number; + + /** Unmount transition duration in ms */ + exitTransitionDuration?: number; + + /** Mount/unmount transition timing function, defaults to theme.transitionTimingFunction */ + transitionTimingFunction?: string; + + /** Tooltip z-index */ + zIndex?: number; } const defaultProps: Partial = { openDelay: 0, closeDelay: 0, - gutter: 0, color: 'gray', disabled: false, position: 'right', @@ -70,8 +80,6 @@ const defaultProps: Partial = { zIndex: getDefaultZIndex('popover'), width: 'auto', wrapLines: false, - positionDependencies: [], - withinPortal: true, }; export const FloatingTooltip = forwardRef( @@ -82,7 +90,6 @@ export const FloatingTooltip = forwardRef( children, openDelay, closeDelay, - gutter, color, radius, disabled, @@ -93,8 +100,6 @@ export const FloatingTooltip = forwardRef( transitionTimingFunction, width, wrapLines, - positionDependencies, - withinPortal, tooltipRef, tooltipId, classNames, @@ -115,8 +120,7 @@ export const FloatingTooltip = forwardRef( const [opened, setOpened] = useState(false); const { ref: mouseRef, x, y } = useMouse(); const visible = opened && !disabled; - const [referenceElement, setReferenceElement] = useState(null); - const mergedRefs = useMergedRef(ref, setReferenceElement, mouseRef); + const mergedRefs = useMergedRef(ref, mouseRef); const coordinates = useMemo(() => { // There's no way to get the exact size of the // cursor using JS, however most OS's use 32x32 @@ -129,22 +133,22 @@ export const FloatingTooltip = forwardRef( case 'top': return { left: x - tooltipWidth / 2, - top: y, + top: y - tooltipHeight, }; case 'left': return { left: x - tooltipWidth - estimatedCursorSize / 2, - top: y + estimatedCursorSize, + top: y, }; case 'right': return { left: x + estimatedCursorSize / 2, - top: y + estimatedCursorSize, + top: y, }; case 'bottom': return { left: x - tooltipWidth / 2, - top: y + tooltipHeight + estimatedCursorSize, + top: y + tooltipHeight, }; default: return { @@ -202,30 +206,31 @@ export const FloatingTooltip = forwardRef( ref={mergedRefs} {...others} > - - - {label} - - + {(transitionStyles) => ( +
+
+ + {label} + +
+
+ )} + {children}
); From 1936a65e92fc38de01a920bf1442585483881845 Mon Sep 17 00:00:00 2001 From: wes337 Date: Sun, 10 Apr 2022 12:50:34 +0300 Subject: [PATCH 6/7] [@mantine/core] Tooltip: fix floating tooltip test, add position deps to coordinates array --- .../Tooltip/FloatingTooltip/FloatingTooltip.test.tsx | 1 - .../components/Tooltip/FloatingTooltip/FloatingTooltip.tsx | 7 ++++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/mantine-core/src/components/Tooltip/FloatingTooltip/FloatingTooltip.test.tsx b/src/mantine-core/src/components/Tooltip/FloatingTooltip/FloatingTooltip.test.tsx index 14ba7492299..d019087fa73 100644 --- a/src/mantine-core/src/components/Tooltip/FloatingTooltip/FloatingTooltip.test.tsx +++ b/src/mantine-core/src/components/Tooltip/FloatingTooltip/FloatingTooltip.test.tsx @@ -5,7 +5,6 @@ import { itRendersChildren, itSupportsSystemProps, renderWithAct, actAsync } fro import { FloatingTooltip, FloatingTooltipProps } from './FloatingTooltip'; const defaultProps: FloatingTooltipProps = { - withinPortal: false, label: 'test-tooltip', children: 'test-target', transitionDuration: 0, diff --git a/src/mantine-core/src/components/Tooltip/FloatingTooltip/FloatingTooltip.tsx b/src/mantine-core/src/components/Tooltip/FloatingTooltip/FloatingTooltip.tsx index 4c2437681eb..8f4e66b08bc 100644 --- a/src/mantine-core/src/components/Tooltip/FloatingTooltip/FloatingTooltip.tsx +++ b/src/mantine-core/src/components/Tooltip/FloatingTooltip/FloatingTooltip.tsx @@ -50,6 +50,9 @@ export interface FloatingTooltipProps /** Tooltip id to bind aria-describedby */ tooltipId?: string; + /** useEffect dependencies to force update tooltip position */ + positionDependencies?: any[]; + /** Position of the tooltip relative to the cursor */ position?: 'top' | 'left' | 'bottom' | 'right'; @@ -80,6 +83,7 @@ const defaultProps: Partial = { zIndex: getDefaultZIndex('popover'), width: 'auto', wrapLines: false, + positionDependencies: [], }; export const FloatingTooltip = forwardRef( @@ -100,6 +104,7 @@ export const FloatingTooltip = forwardRef( transitionTimingFunction, width, wrapLines, + positionDependencies, tooltipRef, tooltipId, classNames, @@ -156,7 +161,7 @@ export const FloatingTooltip = forwardRef( top: y || 0, }; } - }, [x, y]); + }, [x, y, ...positionDependencies]); const handleOpen = () => { window.clearTimeout(closeTimeoutRef.current); From a647697b8e5918b84156afbc38b375e45c91f6f8 Mon Sep 17 00:00:00 2001 From: wes337 Date: Sun, 10 Apr 2022 12:55:01 +0300 Subject: [PATCH 7/7] [@mantine/core] Tooltip: remove extra div --- .../FloatingTooltip/FloatingTooltip.tsx | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/mantine-core/src/components/Tooltip/FloatingTooltip/FloatingTooltip.tsx b/src/mantine-core/src/components/Tooltip/FloatingTooltip/FloatingTooltip.tsx index 8f4e66b08bc..17bfd0b1fae 100644 --- a/src/mantine-core/src/components/Tooltip/FloatingTooltip/FloatingTooltip.tsx +++ b/src/mantine-core/src/components/Tooltip/FloatingTooltip/FloatingTooltip.tsx @@ -219,20 +219,18 @@ export const FloatingTooltip = forwardRef( timingFunction={transitionTimingFunction} > {(transitionStyles) => ( -
-
- - {label} - -
+
+ + {label} +
)}