@pushwoosh/dumb-components 1.1.154 → 1.1.156
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/Tooltip/Tooltip.d.ts +4 -2
- package/Tooltip/Tooltip.js +84 -39
- package/Tooltip/constants.d.ts +2 -0
- package/Tooltip/constants.js +2 -0
- package/Tooltip/maps.d.ts +3 -34
- package/Tooltip/maps.js +2 -135
- package/Tooltip/styles.d.ts +3 -4
- package/Tooltip/styles.js +10 -19
- package/Tooltip/types.d.ts +2 -2
- package/Tooltip/useTooltipPosition.d.ts +27 -0
- package/Tooltip/useTooltipPosition.js +64 -0
- package/helpers/assignRef.d.ts +3 -0
- package/helpers/assignRef.js +8 -0
- package/helpers/index.d.ts +1 -0
- package/helpers/index.js +1 -0
- package/package.json +1 -1
package/Tooltip/Tooltip.d.ts
CHANGED
|
@@ -2,9 +2,11 @@ import { type ReactElement } from 'react';
|
|
|
2
2
|
import type { TooltipProps } from './types';
|
|
3
3
|
/**
|
|
4
4
|
* Wraps an element and shows a contextual tooltip on hover/focus, with configurable
|
|
5
|
-
* position and width.
|
|
5
|
+
* position and width. Positioning is handled by floating-ui, so the tooltip flips to a
|
|
6
|
+
* fallback placement when the requested one would overflow the viewport. Use
|
|
7
|
+
* {@link TooltipTrigger} for a standalone help icon.
|
|
6
8
|
*
|
|
7
9
|
* @example
|
|
8
10
|
* <Tooltip content="Copy to clipboard" position="top-middle"><IconButton /></Tooltip>
|
|
9
11
|
*/
|
|
10
|
-
export declare function Tooltip({
|
|
12
|
+
export declare function Tooltip({ content, position, offset, arrowOffset, maxWidth, zIndex, isDisabled, isVisible, reference, children, }: TooltipProps): ReactElement;
|
package/Tooltip/Tooltip.js
CHANGED
|
@@ -1,53 +1,98 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { cloneElement, isValidElement, useCallback, useEffect, useState } from 'react';
|
|
3
|
+
import { createPortal } from 'react-dom';
|
|
4
|
+
import { assignRef } from '../helpers';
|
|
5
|
+
import { DEFAULT_MAX_WIDTH } from './constants';
|
|
6
|
+
import { Arrow, TooltipBox } from './styles';
|
|
7
|
+
import { useTooltipPosition } from './useTooltipPosition';
|
|
4
8
|
/**
|
|
5
9
|
* Wraps an element and shows a contextual tooltip on hover/focus, with configurable
|
|
6
|
-
* position and width.
|
|
10
|
+
* position and width. Positioning is handled by floating-ui, so the tooltip flips to a
|
|
11
|
+
* fallback placement when the requested one would overflow the viewport. Use
|
|
12
|
+
* {@link TooltipTrigger} for a standalone help icon.
|
|
7
13
|
*
|
|
8
14
|
* @example
|
|
9
15
|
* <Tooltip content="Copy to clipboard" position="top-middle"><IconButton /></Tooltip>
|
|
10
16
|
*/
|
|
11
17
|
export function Tooltip({
|
|
18
|
+
content,
|
|
12
19
|
position = 'top-start',
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
maxWidth =
|
|
20
|
+
offset,
|
|
21
|
+
arrowOffset,
|
|
22
|
+
maxWidth = DEFAULT_MAX_WIDTH,
|
|
16
23
|
zIndex = 999999,
|
|
17
24
|
isDisabled,
|
|
18
25
|
isVisible,
|
|
19
|
-
|
|
26
|
+
reference,
|
|
27
|
+
children
|
|
20
28
|
}) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
placement
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
29
|
+
const isControlled = isVisible !== undefined;
|
|
30
|
+
const [isHovered, setIsHovered] = useState(false);
|
|
31
|
+
const [referenceEl, setReferenceEl] = useState(null);
|
|
32
|
+
const isOpen = !isDisabled && (isControlled ? Boolean(isVisible) : isHovered);
|
|
33
|
+
const {
|
|
34
|
+
refs,
|
|
35
|
+
floatingStyles,
|
|
36
|
+
placement,
|
|
37
|
+
arrowRef,
|
|
38
|
+
arrowStyles
|
|
39
|
+
} = useTooltipPosition({
|
|
40
|
+
position,
|
|
41
|
+
offset,
|
|
42
|
+
arrowOffset,
|
|
43
|
+
isOpen
|
|
44
|
+
});
|
|
45
|
+
const {
|
|
46
|
+
setReference
|
|
47
|
+
} = refs;
|
|
48
|
+
const originalRef = isValidElement(children) ? children.ref : undefined;
|
|
49
|
+
const setChildRef = useCallback(node => {
|
|
50
|
+
setReferenceEl(node);
|
|
51
|
+
assignRef(originalRef, node);
|
|
52
|
+
}, [originalRef]);
|
|
53
|
+
const externalReferenceEl = (reference === null || reference === void 0 ? void 0 : reference.current) ?? null;
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
if (reference) {
|
|
56
|
+
setReferenceEl(externalReferenceEl);
|
|
57
|
+
}
|
|
58
|
+
}, [reference, externalReferenceEl]);
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
setReference(referenceEl);
|
|
61
|
+
}, [referenceEl, setReference]);
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (isControlled || !referenceEl) {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
const show = () => setIsHovered(true);
|
|
67
|
+
const hide = () => setIsHovered(false);
|
|
68
|
+
referenceEl.addEventListener('mouseenter', show);
|
|
69
|
+
referenceEl.addEventListener('mouseleave', hide);
|
|
70
|
+
referenceEl.addEventListener('focusin', show);
|
|
71
|
+
referenceEl.addEventListener('focusout', hide);
|
|
72
|
+
return () => {
|
|
73
|
+
referenceEl.removeEventListener('mouseenter', show);
|
|
74
|
+
referenceEl.removeEventListener('mouseleave', hide);
|
|
75
|
+
referenceEl.removeEventListener('focusin', show);
|
|
76
|
+
referenceEl.removeEventListener('focusout', hide);
|
|
77
|
+
};
|
|
78
|
+
}, [referenceEl, isControlled]);
|
|
79
|
+
const cloneWithRef = cloneElement;
|
|
80
|
+
const anchor = children && isValidElement(children) && !reference ? cloneWithRef(children, {
|
|
81
|
+
ref: setChildRef
|
|
82
|
+
}) : children ?? null;
|
|
83
|
+
return _jsxs(_Fragment, {
|
|
84
|
+
children: [anchor, isOpen && referenceEl && createPortal(_jsxs(TooltipBox, {
|
|
85
|
+
ref: refs.setFloating,
|
|
86
|
+
style: {
|
|
87
|
+
...floatingStyles,
|
|
88
|
+
zIndex
|
|
89
|
+
},
|
|
90
|
+
"$maxWidth": maxWidth,
|
|
91
|
+
"data-placement": placement,
|
|
92
|
+
children: [content, _jsx(Arrow, {
|
|
93
|
+
ref: arrowRef,
|
|
94
|
+
style: arrowStyles
|
|
95
|
+
})]
|
|
96
|
+
}), document.body)]
|
|
52
97
|
});
|
|
53
98
|
}
|
package/Tooltip/maps.d.ts
CHANGED
|
@@ -1,41 +1,10 @@
|
|
|
1
|
+
import type { Placement } from '@floating-ui/react-dom';
|
|
1
2
|
import type { FC } from 'react';
|
|
2
3
|
import { Color } from '@pushwoosh/kit-constants';
|
|
3
4
|
import { type TooltipTriggerView } from './TooltipTrigger';
|
|
4
5
|
import type { TooltipPosition } from './types';
|
|
5
|
-
export declare const
|
|
6
|
-
|
|
7
|
-
'top-middle': "top";
|
|
8
|
-
'top-end': "top-end";
|
|
9
|
-
'right-start': "right-start";
|
|
10
|
-
'right-middle': "right";
|
|
11
|
-
'right-end': "right-end";
|
|
12
|
-
'bottom-start': "bottom-start";
|
|
13
|
-
'bottom-middle': "bottom";
|
|
14
|
-
'bottom-end': "bottom-end";
|
|
15
|
-
'left-start': "left-start";
|
|
16
|
-
'left-middle': "left";
|
|
17
|
-
'left-end': "left-end";
|
|
18
|
-
};
|
|
19
|
-
export declare const TooltipPositionToTippyOffsetMap: Record<TooltipPosition, [number, number]>;
|
|
20
|
-
export declare const TooltipPositionToArrowOffsetMap: {
|
|
21
|
-
'top-start': string;
|
|
22
|
-
'top-middle': string;
|
|
23
|
-
'top-end': string;
|
|
24
|
-
'right-start': string;
|
|
25
|
-
'right-middle': string;
|
|
26
|
-
'right-end': string;
|
|
27
|
-
'bottom-start': string;
|
|
28
|
-
'bottom-middle': string;
|
|
29
|
-
'bottom-end': string;
|
|
30
|
-
'left-start': string;
|
|
31
|
-
'left-middle': string;
|
|
32
|
-
'left-end': string;
|
|
33
|
-
};
|
|
34
|
-
export declare function getTransform(position: TooltipPosition): "none" | "translateX(-50%) translateY(50%) rotate(45deg);" | "translateX(50%) translateY(50%) rotate(45deg);" | "translateX(-50%) translateY(-50%) rotate(45deg);" | "translateX(50%) translateY(-50%) rotate(45deg);";
|
|
35
|
-
export declare function getTopPosition(position: TooltipPosition, offset: string): string;
|
|
36
|
-
export declare function getRightPosition(position: TooltipPosition, offset: string): string;
|
|
37
|
-
export declare function getBottomPosition(position: TooltipPosition, offset: string): string;
|
|
38
|
-
export declare function getLeftPosition(position: TooltipPosition, offset: string): string;
|
|
6
|
+
export declare const TooltipPositionToFloatingPlacementMap: Record<TooltipPosition, Placement>;
|
|
7
|
+
export declare const TooltipPositionToOffsetMap: Record<TooltipPosition, [number, number]>;
|
|
39
8
|
export declare const TooltipTriggerViewMap: Record<TooltipTriggerView, {
|
|
40
9
|
color: Color;
|
|
41
10
|
hoverColor: Color;
|
package/Tooltip/maps.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Color } from '@pushwoosh/kit-constants';
|
|
2
2
|
import { DangerTriangleIcon, HelpRoundIcon, InfoRoundIcon, WarningRoundIcon } from '@pushwoosh/kit-icons';
|
|
3
|
-
export const
|
|
3
|
+
export const TooltipPositionToFloatingPlacementMap = {
|
|
4
4
|
'top-start': 'top-start',
|
|
5
5
|
'top-middle': 'top',
|
|
6
6
|
'top-end': 'top-end',
|
|
@@ -14,7 +14,7 @@ export const TooltipPositionToTippyPlacementMap = {
|
|
|
14
14
|
'left-middle': 'left',
|
|
15
15
|
'left-end': 'left-end'
|
|
16
16
|
};
|
|
17
|
-
export const
|
|
17
|
+
export const TooltipPositionToOffsetMap = {
|
|
18
18
|
'top-start': [-6, 8],
|
|
19
19
|
'top-middle': [0, 8],
|
|
20
20
|
'top-end': [6, 8],
|
|
@@ -28,139 +28,6 @@ export const TooltipPositionToTippyOffsetMap = {
|
|
|
28
28
|
'left-middle': [0, 8],
|
|
29
29
|
'left-end': [6, 8]
|
|
30
30
|
};
|
|
31
|
-
export const TooltipPositionToArrowOffsetMap = {
|
|
32
|
-
'top-start': '24px',
|
|
33
|
-
'top-middle': '50%',
|
|
34
|
-
'top-end': '24px',
|
|
35
|
-
'right-start': '24px',
|
|
36
|
-
'right-middle': '50%',
|
|
37
|
-
'right-end': '24px',
|
|
38
|
-
'bottom-start': '24px',
|
|
39
|
-
'bottom-middle': '50%',
|
|
40
|
-
'bottom-end': '24px',
|
|
41
|
-
'left-start': '24px',
|
|
42
|
-
'left-middle': '50%',
|
|
43
|
-
'left-end': '24px'
|
|
44
|
-
};
|
|
45
|
-
export function getTransform(position) {
|
|
46
|
-
switch (position) {
|
|
47
|
-
case 'top-start':
|
|
48
|
-
return 'translateX(-50%) translateY(50%) rotate(45deg);';
|
|
49
|
-
case 'top-middle':
|
|
50
|
-
return 'translateX(-50%) translateY(50%) rotate(45deg);';
|
|
51
|
-
case 'top-end':
|
|
52
|
-
return 'translateX(50%) translateY(50%) rotate(45deg);';
|
|
53
|
-
case 'right-start':
|
|
54
|
-
return 'translateX(-50%) translateY(-50%) rotate(45deg);';
|
|
55
|
-
case 'right-middle':
|
|
56
|
-
return 'translateX(-50%) translateY(-50%) rotate(45deg);';
|
|
57
|
-
case 'right-end':
|
|
58
|
-
return 'translateX(-50%) translateY(50%) rotate(45deg);';
|
|
59
|
-
case 'bottom-start':
|
|
60
|
-
return 'translateX(-50%) translateY(-50%) rotate(45deg);';
|
|
61
|
-
case 'bottom-middle':
|
|
62
|
-
return 'translateX(-50%) translateY(-50%) rotate(45deg);';
|
|
63
|
-
case 'bottom-end':
|
|
64
|
-
return 'translateX(50%) translateY(-50%) rotate(45deg);';
|
|
65
|
-
case 'left-start':
|
|
66
|
-
return 'translateX(50%) translateY(-50%) rotate(45deg);';
|
|
67
|
-
case 'left-middle':
|
|
68
|
-
return 'translateX(50%) translateY(-50%) rotate(45deg);';
|
|
69
|
-
case 'left-end':
|
|
70
|
-
return 'translateX(50%) translateY(50%) rotate(45deg);';
|
|
71
|
-
default:
|
|
72
|
-
console.error(`[Tooltip]: unknown position: ${position}!`);
|
|
73
|
-
return 'none';
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
export function getTopPosition(position, offset) {
|
|
77
|
-
switch (position) {
|
|
78
|
-
case 'top-start':
|
|
79
|
-
case 'top-middle':
|
|
80
|
-
case 'top-end':
|
|
81
|
-
case 'right-end':
|
|
82
|
-
case 'left-end':
|
|
83
|
-
return 'auto';
|
|
84
|
-
case 'right-start':
|
|
85
|
-
case 'right-middle':
|
|
86
|
-
case 'left-start':
|
|
87
|
-
case 'left-middle':
|
|
88
|
-
return offset;
|
|
89
|
-
case 'bottom-start':
|
|
90
|
-
case 'bottom-middle':
|
|
91
|
-
case 'bottom-end':
|
|
92
|
-
return '0';
|
|
93
|
-
default:
|
|
94
|
-
console.error(`[Tooltip]: unknown position: ${position}!`);
|
|
95
|
-
return 'auto';
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
export function getRightPosition(position, offset) {
|
|
99
|
-
switch (position) {
|
|
100
|
-
case 'top-start':
|
|
101
|
-
case 'top-middle':
|
|
102
|
-
case 'right-start':
|
|
103
|
-
case 'right-middle':
|
|
104
|
-
case 'right-end':
|
|
105
|
-
case 'bottom-start':
|
|
106
|
-
case 'bottom-middle':
|
|
107
|
-
return 'auto';
|
|
108
|
-
case 'top-end':
|
|
109
|
-
case 'bottom-end':
|
|
110
|
-
return offset;
|
|
111
|
-
case 'left-end':
|
|
112
|
-
case 'left-start':
|
|
113
|
-
case 'left-middle':
|
|
114
|
-
return '0';
|
|
115
|
-
default:
|
|
116
|
-
console.error(`[Tooltip]: unknown position: ${position}!`);
|
|
117
|
-
return 'auto';
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
export function getBottomPosition(position, offset) {
|
|
121
|
-
switch (position) {
|
|
122
|
-
case 'top-start':
|
|
123
|
-
case 'top-middle':
|
|
124
|
-
case 'top-end':
|
|
125
|
-
return '0';
|
|
126
|
-
case 'right-end':
|
|
127
|
-
case 'left-end':
|
|
128
|
-
return offset;
|
|
129
|
-
case 'bottom-start':
|
|
130
|
-
case 'bottom-middle':
|
|
131
|
-
case 'bottom-end':
|
|
132
|
-
case 'right-start':
|
|
133
|
-
case 'right-middle':
|
|
134
|
-
case 'left-start':
|
|
135
|
-
case 'left-middle':
|
|
136
|
-
return 'auto';
|
|
137
|
-
default:
|
|
138
|
-
console.error(`[Tooltip]: unknown position: ${position}!`);
|
|
139
|
-
return 'auto';
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
export function getLeftPosition(position, offset) {
|
|
143
|
-
switch (position) {
|
|
144
|
-
case 'top-start':
|
|
145
|
-
case 'top-middle':
|
|
146
|
-
case 'bottom-start':
|
|
147
|
-
case 'bottom-middle':
|
|
148
|
-
return offset;
|
|
149
|
-
case 'top-end':
|
|
150
|
-
case 'bottom-end':
|
|
151
|
-
case 'left-end':
|
|
152
|
-
case 'left-start':
|
|
153
|
-
case 'left-middle':
|
|
154
|
-
return 'auto';
|
|
155
|
-
case 'right-start':
|
|
156
|
-
case 'right-end':
|
|
157
|
-
case 'right-middle':
|
|
158
|
-
return '0';
|
|
159
|
-
default:
|
|
160
|
-
console.error(`[Tooltip]: unknown position: ${position}!`);
|
|
161
|
-
return 'auto';
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
31
|
export const TooltipTriggerViewMap = {
|
|
165
32
|
info: {
|
|
166
33
|
color: Color.LOCKED,
|
package/Tooltip/styles.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { Color } from '@pushwoosh/kit-constants';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
$arrowOffset: string;
|
|
5
|
-
$position: TooltipPosition;
|
|
2
|
+
export declare const TooltipBox: import("styled-components").StyledComponent<"div", any, {
|
|
3
|
+
$maxWidth?: number | "none";
|
|
6
4
|
}, never>;
|
|
5
|
+
export declare const Arrow: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
7
6
|
export declare const HelpIconWrapper: import("styled-components").StyledComponent<"div", any, import("@pushwoosh/kit-helpers/styled-helpers").CommonBoxProps & {
|
|
8
7
|
$alignContent?: import("@pushwoosh/kit-helpers/styled-helpers").AlignContentValue | undefined;
|
|
9
8
|
$alignItems?: import("@pushwoosh/kit-helpers/styled-helpers").ItemAlignmentValue | undefined;
|
package/Tooltip/styles.js
CHANGED
|
@@ -1,29 +1,20 @@
|
|
|
1
|
-
import Tippy from '@tippyjs/react';
|
|
2
1
|
import styled from 'styled-components';
|
|
3
2
|
import { Color, FontSize, ShapeRadius } from '@pushwoosh/kit-constants';
|
|
4
3
|
import { Horizontal } from '@pushwoosh/kit-helpers';
|
|
5
|
-
import {
|
|
6
|
-
export const TooltipBox = styled
|
|
4
|
+
import { DEFAULT_MAX_WIDTH } from './constants';
|
|
5
|
+
export const TooltipBox = styled.div.withConfig({
|
|
7
6
|
displayName: "TooltipBox",
|
|
8
7
|
componentId: "sc-1hariht-0"
|
|
9
|
-
})(["
|
|
10
|
-
$
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
})
|
|
16
|
-
$position,
|
|
17
|
-
$arrowOffset
|
|
18
|
-
}) => getBottomPosition($position, $arrowOffset), ({
|
|
19
|
-
$position,
|
|
20
|
-
$arrowOffset
|
|
21
|
-
}) => getLeftPosition($position, $arrowOffset), Color.MAIN, ({
|
|
22
|
-
$position
|
|
23
|
-
}) => getTransform($position), Color.CLEAR, Color.MAIN, ShapeRadius.DIALOG, FontSize.REGULAR);
|
|
8
|
+
})(["padding:12px;color:", ";background-color:", ";border-radius:", ";font-size:", ";line-height:inherit;outline:0;pointer-events:none;max-width:", ";"], Color.CLEAR, Color.MAIN, ShapeRadius.DIALOG, FontSize.REGULAR, ({
|
|
9
|
+
$maxWidth
|
|
10
|
+
}) => $maxWidth === 'none' ? 'min(var(--pw-page-max-width, 100vw), calc(100vw - 16px))' : `min(${$maxWidth ?? DEFAULT_MAX_WIDTH}px, var(--pw-page-max-width, 100vw), calc(100vw - 16px))`);
|
|
11
|
+
export const Arrow = styled.div.withConfig({
|
|
12
|
+
displayName: "Arrow",
|
|
13
|
+
componentId: "sc-1hariht-1"
|
|
14
|
+
})(["position:absolute;width:10px;height:10px;border-radius:2px;background-color:", ";transform:rotate(45deg);"], Color.MAIN);
|
|
24
15
|
export const HelpIconWrapper = styled(Horizontal).withConfig({
|
|
25
16
|
displayName: "HelpIconWrapper",
|
|
26
|
-
componentId: "sc-1hariht-
|
|
17
|
+
componentId: "sc-1hariht-2"
|
|
27
18
|
})(["color:", ";", ""], ({
|
|
28
19
|
$color
|
|
29
20
|
}) => $color, ({
|
package/Tooltip/types.d.ts
CHANGED
|
@@ -7,9 +7,9 @@ export type TooltipProps = {
|
|
|
7
7
|
readonly content: ReactNode;
|
|
8
8
|
/** Placement relative to the anchor (default `top-start`). */
|
|
9
9
|
readonly position?: TooltipPosition;
|
|
10
|
-
/**
|
|
10
|
+
/** `[skidding, distance]` offset from the anchor; defaults per position. */
|
|
11
11
|
readonly offset?: [number, number];
|
|
12
|
-
/**
|
|
12
|
+
/** Min gap (px) the arrow keeps from the tooltip corners; arrow points at the anchor (default `12`). */
|
|
13
13
|
readonly arrowOffset?: string;
|
|
14
14
|
/** Max width in pixels, or `'none'` (default `240`). */
|
|
15
15
|
readonly maxWidth?: number | 'none';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type CSSProperties } from 'react';
|
|
2
|
+
import type { TooltipPosition } from './types';
|
|
3
|
+
type Args = {
|
|
4
|
+
position: TooltipPosition;
|
|
5
|
+
offset?: [number, number] | undefined;
|
|
6
|
+
arrowOffset?: string | undefined;
|
|
7
|
+
isOpen: boolean;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Positions the tooltip relative to its anchor via floating-ui: `flip`/`shift` pick a
|
|
11
|
+
* fallback placement when the requested one overflows the viewport, and `arrow` keeps the
|
|
12
|
+
* arrow pointing at the anchor's center. `arrowOffset` only sets the minimum gap (px) the
|
|
13
|
+
* arrow keeps from the tooltip corners. Repositions on scroll/resize while open.
|
|
14
|
+
*/
|
|
15
|
+
export declare function useTooltipPosition({ position, offset: offsetProp, arrowOffset, isOpen, }: Args): {
|
|
16
|
+
refs: {
|
|
17
|
+
reference: import("react").MutableRefObject<import("@floating-ui/react-dom").ReferenceType | null>;
|
|
18
|
+
floating: React.MutableRefObject<HTMLElement | null>;
|
|
19
|
+
setReference: (node: import("@floating-ui/react-dom").ReferenceType | null) => void;
|
|
20
|
+
setFloating: (node: HTMLElement | null) => void;
|
|
21
|
+
};
|
|
22
|
+
floatingStyles: CSSProperties;
|
|
23
|
+
placement: import("@floating-ui/utils").Placement;
|
|
24
|
+
arrowRef: import("react").RefObject<HTMLDivElement>;
|
|
25
|
+
arrowStyles: CSSProperties;
|
|
26
|
+
};
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { arrow, autoUpdate, flip, offset, shift, useFloating } from '@floating-ui/react-dom';
|
|
2
|
+
import { useRef } from 'react';
|
|
3
|
+
import { DEFAULT_ARROW_PADDING } from './constants';
|
|
4
|
+
import { TooltipPositionToFloatingPlacementMap, TooltipPositionToOffsetMap } from './maps';
|
|
5
|
+
const ArrowStaticSideMap = {
|
|
6
|
+
top: 'bottom',
|
|
7
|
+
right: 'left',
|
|
8
|
+
bottom: 'top',
|
|
9
|
+
left: 'right'
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Positions the tooltip relative to its anchor via floating-ui: `flip`/`shift` pick a
|
|
13
|
+
* fallback placement when the requested one overflows the viewport, and `arrow` keeps the
|
|
14
|
+
* arrow pointing at the anchor's center. `arrowOffset` only sets the minimum gap (px) the
|
|
15
|
+
* arrow keeps from the tooltip corners. Repositions on scroll/resize while open.
|
|
16
|
+
*/
|
|
17
|
+
export function useTooltipPosition({
|
|
18
|
+
position,
|
|
19
|
+
offset: offsetProp,
|
|
20
|
+
arrowOffset,
|
|
21
|
+
isOpen
|
|
22
|
+
}) {
|
|
23
|
+
const arrowRef = useRef(null);
|
|
24
|
+
const [skidding, distance] = offsetProp ?? TooltipPositionToOffsetMap[position];
|
|
25
|
+
const parsedPadding = arrowOffset != null ? parseFloat(arrowOffset) : NaN;
|
|
26
|
+
const arrowPadding = Number.isFinite(parsedPadding) ? parsedPadding : DEFAULT_ARROW_PADDING;
|
|
27
|
+
const {
|
|
28
|
+
refs,
|
|
29
|
+
floatingStyles,
|
|
30
|
+
placement,
|
|
31
|
+
middlewareData
|
|
32
|
+
} = useFloating({
|
|
33
|
+
open: isOpen,
|
|
34
|
+
strategy: 'fixed',
|
|
35
|
+
placement: TooltipPositionToFloatingPlacementMap[position],
|
|
36
|
+
middleware: [offset({
|
|
37
|
+
mainAxis: distance,
|
|
38
|
+
crossAxis: skidding
|
|
39
|
+
}), flip(), shift({
|
|
40
|
+
padding: 8
|
|
41
|
+
}), arrow({
|
|
42
|
+
element: arrowRef,
|
|
43
|
+
padding: arrowPadding
|
|
44
|
+
})],
|
|
45
|
+
whileElementsMounted: autoUpdate
|
|
46
|
+
});
|
|
47
|
+
const side = placement.split('-')[0];
|
|
48
|
+
const {
|
|
49
|
+
x: arrowX,
|
|
50
|
+
y: arrowY
|
|
51
|
+
} = middlewareData.arrow ?? {};
|
|
52
|
+
const arrowStyles = {
|
|
53
|
+
left: arrowX != null ? `${arrowX}px` : '',
|
|
54
|
+
top: arrowY != null ? `${arrowY}px` : '',
|
|
55
|
+
[ArrowStaticSideMap[side]]: '-5px'
|
|
56
|
+
};
|
|
57
|
+
return {
|
|
58
|
+
refs,
|
|
59
|
+
floatingStyles,
|
|
60
|
+
placement,
|
|
61
|
+
arrowRef,
|
|
62
|
+
arrowStyles
|
|
63
|
+
};
|
|
64
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './assignRef';
|
package/helpers/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './assignRef';
|