@pushwoosh/dumb-components 1.1.153 → 1.1.155

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.
@@ -55,6 +55,11 @@ export function AutosizeInput(props) {
55
55
  const formattedValue = maxLength ? event.currentTarget.value.slice(0, maxLength) : event.currentTarget.value;
56
56
  onChange === null || onChange === void 0 || onChange(formattedValue.replace(/\n/g, ''));
57
57
  };
58
+ const onFocus = () => {
59
+ if (value === DEFAULT_EMPTY_VALUE) {
60
+ onChange === null || onChange === void 0 || onChange('');
61
+ }
62
+ };
58
63
  const onBlur = () => {
59
64
  if (value === '') {
60
65
  onChange === null || onChange === void 0 || onChange(defaultValue.current);
@@ -73,6 +78,7 @@ export function AutosizeInput(props) {
73
78
  placeholder: placeholder,
74
79
  onKeyDown: onKeyDown,
75
80
  onChange: onChangeHandler,
81
+ onFocus: onFocus,
76
82
  onBlur: onBlur
77
83
  }), _jsx("span", {
78
84
  ref: hiddenValueRef,
@@ -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. Use {@link TooltipTrigger} for a standalone help icon.
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({ position, arrowOffset, offset, maxWidth, zIndex, isDisabled, isVisible, ...rest }: TooltipProps): ReactElement;
12
+ export declare function Tooltip({ content, position, offset, arrowOffset, maxWidth, zIndex, isDisabled, isVisible, reference, children, }: TooltipProps): ReactElement;
@@ -1,53 +1,99 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { TooltipPositionToArrowOffsetMap, TooltipPositionToTippyOffsetMap, TooltipPositionToTippyPlacementMap } from './maps';
3
- import { TooltipBox } from './styles';
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. Use {@link TooltipTrigger} for a standalone help icon.
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
- arrowOffset = TooltipPositionToArrowOffsetMap[position],
14
- offset = TooltipPositionToTippyOffsetMap[position],
15
- maxWidth = 240,
20
+ offset,
21
+ arrowOffset,
22
+ maxWidth = DEFAULT_MAX_WIDTH,
16
23
  zIndex = 999999,
17
24
  isDisabled,
18
25
  isVisible,
19
- ...rest
26
+ reference,
27
+ children
20
28
  }) {
21
- return _jsx(TooltipBox, {
22
- animation: false,
23
- delay: 0,
24
- duration: 0,
25
- disabled: isDisabled,
26
- maxWidth: maxWidth,
27
- zIndex: zIndex,
28
- placement: TooltipPositionToTippyPlacementMap[position],
29
- visible: isVisible,
30
- "$position": position,
31
- "$arrowOffset": arrowOffset,
32
- popperOptions: {
33
- strategy: 'fixed',
34
- modifiers: [{
35
- name: 'offset',
36
- options: {
37
- offset
38
- }
39
- }, {
40
- name: 'flip',
41
- options: {
42
- fallbackPlacements: []
43
- }
44
- }, {
45
- name: 'preventOverflow',
46
- options: {
47
- mainAxis: false
48
- }
49
- }]
50
- },
51
- ...rest
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
+ maxWidth,
44
+ isOpen
45
+ });
46
+ const {
47
+ setReference
48
+ } = refs;
49
+ const originalRef = isValidElement(children) ? children.ref : undefined;
50
+ const setChildRef = useCallback(node => {
51
+ setReferenceEl(node);
52
+ assignRef(originalRef, node);
53
+ }, [originalRef]);
54
+ const externalReferenceEl = (reference === null || reference === void 0 ? void 0 : reference.current) ?? null;
55
+ useEffect(() => {
56
+ if (reference) {
57
+ setReferenceEl(externalReferenceEl);
58
+ }
59
+ }, [reference, externalReferenceEl]);
60
+ useEffect(() => {
61
+ setReference(referenceEl);
62
+ }, [referenceEl, setReference]);
63
+ useEffect(() => {
64
+ if (isControlled || !referenceEl) {
65
+ return undefined;
66
+ }
67
+ const show = () => setIsHovered(true);
68
+ const hide = () => setIsHovered(false);
69
+ referenceEl.addEventListener('mouseenter', show);
70
+ referenceEl.addEventListener('mouseleave', hide);
71
+ referenceEl.addEventListener('focusin', show);
72
+ referenceEl.addEventListener('focusout', hide);
73
+ return () => {
74
+ referenceEl.removeEventListener('mouseenter', show);
75
+ referenceEl.removeEventListener('mouseleave', hide);
76
+ referenceEl.removeEventListener('focusin', show);
77
+ referenceEl.removeEventListener('focusout', hide);
78
+ };
79
+ }, [referenceEl, isControlled]);
80
+ const cloneWithRef = cloneElement;
81
+ const anchor = children && isValidElement(children) && !reference ? cloneWithRef(children, {
82
+ ref: setChildRef
83
+ }) : children ?? null;
84
+ return _jsxs(_Fragment, {
85
+ children: [anchor, isOpen && referenceEl && createPortal(_jsxs(TooltipBox, {
86
+ ref: refs.setFloating,
87
+ style: {
88
+ ...floatingStyles,
89
+ zIndex
90
+ },
91
+ "$maxWidth": maxWidth,
92
+ "data-placement": placement,
93
+ children: [content, _jsx(Arrow, {
94
+ ref: arrowRef,
95
+ style: arrowStyles
96
+ })]
97
+ }), document.body)]
52
98
  });
53
99
  }
@@ -0,0 +1,2 @@
1
+ export declare const DEFAULT_MAX_WIDTH = 240;
2
+ export declare const DEFAULT_ARROW_PADDING = 12;
@@ -0,0 +1,2 @@
1
+ export const DEFAULT_MAX_WIDTH = 240;
2
+ export const DEFAULT_ARROW_PADDING = 12;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Resolve the legacy `arrowOffset` CSS string into an `arrow()` padding in px — the
3
+ * minimum distance the arrow keeps from the tooltip corners. Accepts `px` values as-is
4
+ * and `%` values relative to the tooltip's max cross size (`maxWidth`, or the default
5
+ * when unbounded), so both forms used with the old tippy tooltip keep working.
6
+ */
7
+ export declare function parseArrowPadding(arrowOffset: string | undefined, maxWidth: number | 'none' | undefined): number;
@@ -0,0 +1,21 @@
1
+ import { DEFAULT_ARROW_PADDING, DEFAULT_MAX_WIDTH } from './constants';
2
+ /**
3
+ * Resolve the legacy `arrowOffset` CSS string into an `arrow()` padding in px — the
4
+ * minimum distance the arrow keeps from the tooltip corners. Accepts `px` values as-is
5
+ * and `%` values relative to the tooltip's max cross size (`maxWidth`, or the default
6
+ * when unbounded), so both forms used with the old tippy tooltip keep working.
7
+ */
8
+ export function parseArrowPadding(arrowOffset, maxWidth) {
9
+ if (!arrowOffset) {
10
+ return DEFAULT_ARROW_PADDING;
11
+ }
12
+ const value = parseFloat(arrowOffset);
13
+ if (Number.isNaN(value)) {
14
+ return DEFAULT_ARROW_PADDING;
15
+ }
16
+ if (arrowOffset.trim().endsWith('%')) {
17
+ const base = typeof maxWidth === 'number' ? maxWidth : DEFAULT_MAX_WIDTH;
18
+ return value / 100 * base;
19
+ }
20
+ return value;
21
+ }
package/Tooltip/maps.d.ts CHANGED
@@ -1,41 +1,11 @@
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 TooltipPositionToTippyPlacementMap: {
6
- 'top-start': "top-start";
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]>;
8
+ export declare const TooltipPositionToArrowOffsetMap: Record<TooltipPosition, string>;
39
9
  export declare const TooltipTriggerViewMap: Record<TooltipTriggerView, {
40
10
  color: Color;
41
11
  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 TooltipPositionToTippyPlacementMap = {
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 TooltipPositionToTippyOffsetMap = {
17
+ export const TooltipPositionToOffsetMap = {
18
18
  'top-start': [-6, 8],
19
19
  'top-middle': [0, 8],
20
20
  'top-end': [6, 8],
@@ -42,125 +42,6 @@ export const TooltipPositionToArrowOffsetMap = {
42
42
  'left-middle': '50%',
43
43
  'left-end': '24px'
44
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
45
  export const TooltipTriggerViewMap = {
165
46
  info: {
166
47
  color: Color.LOCKED,
@@ -1,9 +1,8 @@
1
1
  import { Color } from '@pushwoosh/kit-constants';
2
- import type { TooltipPosition } from './types';
3
- export declare const TooltipBox: import("styled-components").StyledComponent<import("react").ForwardRefExoticComponent<import("@tippyjs/react").TippyProps>, any, {
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 { getBottomPosition, getLeftPosition, getRightPosition, getTopPosition, getTransform } from './maps';
6
- export const TooltipBox = styled(Tippy).withConfig({
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
- })(["&::after{content:\"\";position:absolute;top:", ";right:", ";bottom:", ";left:", ";width:10px;height:10px;margin:auto;border-radius:2px;background-color:", ";transform:", ";}&.tippy-box{position:static;display:block;padding:12px;color:", ";background-color:", ";border-radius:", ";font-size:", ";line-height:inherit;outline:0;transition:none;}.tippy-content{position:static;padding:0;z-index:auto;}.tippy-arrow{display:none;}"], ({
10
- $position,
11
- $arrowOffset
12
- }) => getTopPosition($position, $arrowOffset), ({
13
- $position,
14
- $arrowOffset
15
- }) => getRightPosition($position, $arrowOffset), ({
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-1"
17
+ componentId: "sc-1hariht-2"
27
18
  })(["color:", ";", ""], ({
28
19
  $color
29
20
  }) => $color, ({
@@ -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
- /** Tippy `[skidding, distance]` offset; defaults per position. */
10
+ /** `[skidding, distance]` offset from the anchor; defaults per position. */
11
11
  readonly offset?: [number, number];
12
- /** CSS offset of the arrow along its edge. */
12
+ /** Min distance the arrow keeps from the tooltip corners — `px` or `%` of `maxWidth`. */
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
+ maxWidth?: number | 'none' | undefined;
8
+ isOpen: boolean;
9
+ };
10
+ /**
11
+ * Positions the tooltip relative to its anchor via floating-ui: `flip`/`shift` pick a
12
+ * fallback placement when the requested one overflows the viewport, and `arrow` keeps
13
+ * the arrow pointing at the anchor. Repositions on scroll/resize while open.
14
+ */
15
+ export declare function useTooltipPosition({ position, offset: offsetProp, arrowOffset, maxWidth, 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,63 @@
1
+ import { arrow, autoUpdate, flip, offset, shift, useFloating } from '@floating-ui/react-dom';
2
+ import { useRef } from 'react';
3
+ import { parseArrowPadding } from './helpers';
4
+ import { TooltipPositionToArrowOffsetMap, 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
14
+ * the arrow pointing at the anchor. Repositions on scroll/resize while open.
15
+ */
16
+ export function useTooltipPosition({
17
+ position,
18
+ offset: offsetProp,
19
+ arrowOffset,
20
+ maxWidth,
21
+ isOpen
22
+ }) {
23
+ const arrowRef = useRef(null);
24
+ const [skidding, distance] = offsetProp ?? TooltipPositionToOffsetMap[position];
25
+ const arrowPadding = parseArrowPadding(arrowOffset ?? TooltipPositionToArrowOffsetMap[position], maxWidth);
26
+ const {
27
+ refs,
28
+ floatingStyles,
29
+ placement,
30
+ middlewareData
31
+ } = useFloating({
32
+ open: isOpen,
33
+ strategy: 'fixed',
34
+ placement: TooltipPositionToFloatingPlacementMap[position],
35
+ middleware: [offset({
36
+ mainAxis: distance,
37
+ crossAxis: skidding
38
+ }), flip(), shift({
39
+ padding: 8
40
+ }), arrow({
41
+ element: arrowRef,
42
+ padding: arrowPadding
43
+ })],
44
+ whileElementsMounted: autoUpdate
45
+ });
46
+ const side = placement.split('-')[0];
47
+ const {
48
+ x: arrowX,
49
+ y: arrowY
50
+ } = middlewareData.arrow ?? {};
51
+ const arrowStyles = {
52
+ left: arrowX != null ? `${arrowX}px` : '',
53
+ top: arrowY != null ? `${arrowY}px` : '',
54
+ [ArrowStaticSideMap[side]]: '-5px'
55
+ };
56
+ return {
57
+ refs,
58
+ floatingStyles,
59
+ placement,
60
+ arrowRef,
61
+ arrowStyles
62
+ };
63
+ }
@@ -0,0 +1,3 @@
1
+ import type { Ref } from 'react';
2
+ /** Forward a node to a callback or object ref while keeping our own reference in sync. */
3
+ export declare function assignRef(ref: Ref<Element> | undefined, node: Element | null): void;
@@ -0,0 +1,8 @@
1
+ /** Forward a node to a callback or object ref while keeping our own reference in sync. */
2
+ export function assignRef(ref, node) {
3
+ if (typeof ref === 'function') {
4
+ ref(node);
5
+ } else if (ref) {
6
+ ref.current = node;
7
+ }
8
+ }
@@ -0,0 +1 @@
1
+ export * from './assignRef';
@@ -0,0 +1 @@
1
+ export * from './assignRef';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pushwoosh/dumb-components",
3
- "version": "1.1.153",
3
+ "version": "1.1.155",
4
4
  "description": "React components to build Pushwoosh products",
5
5
  "main": "index.js",
6
6
  "module": "index.js",