@sanity/ui 2.6.4 → 2.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.esm.js +23 -22
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +22 -21
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +23 -22
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/core/primitives/tooltip/tooltip.tsx +33 -29
package/package.json
CHANGED
|
@@ -21,12 +21,12 @@ import {
|
|
|
21
21
|
useState,
|
|
22
22
|
useId,
|
|
23
23
|
useImperativeHandle,
|
|
24
|
+
useLayoutEffect,
|
|
24
25
|
} from 'react'
|
|
25
26
|
import {styled} from 'styled-components'
|
|
26
27
|
import {useEffectEvent} from 'use-effect-event'
|
|
27
28
|
import {useArrayProp, usePrefersReducedMotion} from '../../hooks'
|
|
28
29
|
import {useDelayedState} from '../../hooks/useDelayedState'
|
|
29
|
-
import {useMounted} from '../../hooks/useMounted'
|
|
30
30
|
import {origin} from '../../middleware/origin'
|
|
31
31
|
import {useTheme_v2} from '../../theme'
|
|
32
32
|
import type {Placement} from '../../types'
|
|
@@ -86,9 +86,8 @@ export interface TooltipProps extends Omit<LayerProps, 'as'> {
|
|
|
86
86
|
animate?: boolean
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
const Root = styled(Layer)
|
|
89
|
+
const Root = styled(Layer)`
|
|
90
90
|
pointer-events: none;
|
|
91
|
-
max-width: ${({$maxWidth}) => $maxWidth}px;
|
|
92
91
|
`
|
|
93
92
|
|
|
94
93
|
/**
|
|
@@ -128,6 +127,7 @@ export const Tooltip = forwardRef(function Tooltip(
|
|
|
128
127
|
const [referenceElement, setReferenceElement] = useState<HTMLElement | null>(null)
|
|
129
128
|
const arrowRef = useRef<HTMLDivElement | null>(null)
|
|
130
129
|
const rootBoundary: RootBoundary = 'viewport'
|
|
130
|
+
const [tooltipMaxWidth, setTooltipMaxWidth] = useState(0)
|
|
131
131
|
|
|
132
132
|
useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(forwardedRef, () => ref.current)
|
|
133
133
|
|
|
@@ -135,22 +135,6 @@ export const Tooltip = forwardRef(function Tooltip(
|
|
|
135
135
|
const portalElement =
|
|
136
136
|
typeof portalProp === 'string' ? portal.elements?.[portalProp] || null : portal.element
|
|
137
137
|
|
|
138
|
-
const mounted = useMounted()
|
|
139
|
-
// Get the maximum tooltip width (sans tooltip padding)
|
|
140
|
-
// Tooltip width should never exceed the width of either any supplied boundary or portal element.
|
|
141
|
-
// If both portal and boundary elements are provided, use the smaller width of the two.
|
|
142
|
-
const tooltipWidth = useMemo(() => {
|
|
143
|
-
const availableWidths = [
|
|
144
|
-
...(boundaryElement ? [boundaryElement.offsetWidth] : []),
|
|
145
|
-
portalElement?.offsetWidth || mounted
|
|
146
|
-
? document.body.offsetWidth
|
|
147
|
-
: // We don't actually know what the width of the body is during SSR, so we'll just assume it's 800px or larger
|
|
148
|
-
800,
|
|
149
|
-
]
|
|
150
|
-
|
|
151
|
-
return Math.min(...availableWidths) - DEFAULT_TOOLTIP_PADDING * 2
|
|
152
|
-
}, [boundaryElement, mounted, portalElement])
|
|
153
|
-
|
|
154
138
|
const middleware = useMemo(() => {
|
|
155
139
|
const ret: Middleware[] = []
|
|
156
140
|
|
|
@@ -284,6 +268,9 @@ export const Tooltip = forwardRef(function Tooltip(
|
|
|
284
268
|
[childProp?.props, handleIsOpenChange],
|
|
285
269
|
)
|
|
286
270
|
|
|
271
|
+
// Handle closing the tooltip when the mouse leaves the referenceElement
|
|
272
|
+
useCloseOnMouseLeave({handleIsOpenChange, referenceElement, showTooltip})
|
|
273
|
+
|
|
287
274
|
// Close when `disabled` changes to `true`
|
|
288
275
|
useEffect(() => {
|
|
289
276
|
if (disabled && showTooltip) handleIsOpenChange(false)
|
|
@@ -314,8 +301,18 @@ export const Tooltip = forwardRef(function Tooltip(
|
|
|
314
301
|
}
|
|
315
302
|
}, [handleIsOpenChange, showTooltip])
|
|
316
303
|
|
|
317
|
-
//
|
|
318
|
-
|
|
304
|
+
// // Set the max width of the tooltip based on boundaries and portals
|
|
305
|
+
useLayoutEffect(() => {
|
|
306
|
+
// Get the maximum tooltip width (sans tooltip padding)
|
|
307
|
+
// Tooltip width should never exceed the width of either any supplied boundary or portal element.
|
|
308
|
+
// If both portal and boundary elements are provided, use the smaller width of the two.
|
|
309
|
+
const availableWidths = [
|
|
310
|
+
...(boundaryElement ? [boundaryElement.offsetWidth] : []),
|
|
311
|
+
portalElement?.offsetWidth || document.body.offsetWidth,
|
|
312
|
+
]
|
|
313
|
+
|
|
314
|
+
setTooltipMaxWidth(Math.min(...availableWidths) - DEFAULT_TOOLTIP_PADDING * 2)
|
|
315
|
+
}, [boundaryElement, portalElement])
|
|
319
316
|
|
|
320
317
|
const setArrow = useCallback(
|
|
321
318
|
(arrowEl: HTMLDivElement | null) => {
|
|
@@ -379,9 +376,11 @@ export const Tooltip = forwardRef(function Tooltip(
|
|
|
379
376
|
data-ui="Tooltip"
|
|
380
377
|
{...restProps}
|
|
381
378
|
ref={setFloating}
|
|
382
|
-
style={
|
|
379
|
+
style={{
|
|
380
|
+
...floatingStyles,
|
|
381
|
+
maxWidth: tooltipMaxWidth > 0 ? `${tooltipMaxWidth}px` : undefined,
|
|
382
|
+
}}
|
|
383
383
|
zOffset={zOffset}
|
|
384
|
-
$maxWidth={tooltipWidth}
|
|
385
384
|
>
|
|
386
385
|
<TooltipCard
|
|
387
386
|
{...restProps}
|
|
@@ -447,15 +446,16 @@ function useCloseOnMouseLeave({
|
|
|
447
446
|
// Since we don't want the `mouseevent` events to be attached and removed if the `referenceElement` is changed
|
|
448
447
|
// we use a "effect event" (https://19.react.dev/learn/separating-events-from-effects#reading-latest-props-and-state-with-effect-events)
|
|
449
448
|
// in order to always see the latest `referenceElement` value inside the event handler itself.
|
|
450
|
-
const
|
|
449
|
+
const onMouseMove = useEffectEvent((target: EventTarget | null, teardown: () => void) => {
|
|
451
450
|
if (!referenceElement) return
|
|
452
451
|
|
|
453
452
|
const isHoveringReference =
|
|
454
|
-
referenceElement ===
|
|
455
|
-
(event.target instanceof Node && referenceElement.contains(event.target))
|
|
453
|
+
referenceElement === target || (target instanceof Node && referenceElement.contains(target))
|
|
456
454
|
|
|
457
455
|
if (!isHoveringReference) {
|
|
458
456
|
handleIsOpenChange(false)
|
|
457
|
+
// Allow removing the event listener eagerly, to avoid race conditions
|
|
458
|
+
teardown()
|
|
459
459
|
}
|
|
460
460
|
})
|
|
461
461
|
|
|
@@ -465,8 +465,12 @@ function useCloseOnMouseLeave({
|
|
|
465
465
|
useEffect(() => {
|
|
466
466
|
if (!showTooltip) return
|
|
467
467
|
|
|
468
|
-
|
|
468
|
+
const handleMouseMove = (event: MouseEvent) => {
|
|
469
|
+
onMouseMove(event.target, () => window.removeEventListener('mousemove', handleMouseMove))
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
window.addEventListener('mousemove', handleMouseMove)
|
|
469
473
|
|
|
470
|
-
return () => window.removeEventListener('mousemove',
|
|
471
|
-
}, [
|
|
474
|
+
return () => window.removeEventListener('mousemove', handleMouseMove)
|
|
475
|
+
}, [onMouseMove, showTooltip])
|
|
472
476
|
}
|