@pushwoosh/dumb-components 4.7.0 → 4.7.2
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/Calendar/CalendarDropdown/CalendarDropdown.js +9 -4
- package/Calendar/CalendarSuperForm/components/CalendarRangePicker/CalendarRangePicker.js +5 -6
- package/DropdownMenu/components/DropdownMenu/DropdownMenu.js +13 -8
- package/DropdownMenu/components/DropdownMenuSubmenu/DropdownMenuSubmenu.js +6 -3
- package/RichMessageEditor/RichMessageEditor.js +13 -9
- package/Tooltip/Tooltip.js +3 -2
- package/Tooltip/useTooltipPosition.d.ts +1 -1
- package/Tooltip/useTooltipPosition.js +4 -4
- package/hooks/useLayer.js +4 -2
- package/hooks/useThemeName.js +1 -1
- package/package.json +2 -2
- package/shared/dropdownField/useAsyncItems.js +4 -2
- package/shared/dropdownField/useFieldOpenEffects.js +3 -4
|
@@ -66,7 +66,12 @@ export const CalendarDropdown = props => {
|
|
|
66
66
|
setIsOpen(true);
|
|
67
67
|
};
|
|
68
68
|
const {
|
|
69
|
-
refs
|
|
69
|
+
refs: {
|
|
70
|
+
reference,
|
|
71
|
+
floating,
|
|
72
|
+
setReference,
|
|
73
|
+
setFloating
|
|
74
|
+
},
|
|
70
75
|
floatingStyles
|
|
71
76
|
} = useFloating({
|
|
72
77
|
open: isOpen,
|
|
@@ -84,7 +89,7 @@ export const CalendarDropdown = props => {
|
|
|
84
89
|
isOpen,
|
|
85
90
|
onClose: closePopover
|
|
86
91
|
});
|
|
87
|
-
useOnClickOutside([
|
|
92
|
+
useOnClickOutside([reference, floating], () => {
|
|
88
93
|
if (isOpen) closePopover();
|
|
89
94
|
});
|
|
90
95
|
const onChangeHandler = val => {
|
|
@@ -106,7 +111,7 @@ export const CalendarDropdown = props => {
|
|
|
106
111
|
return _jsxs(Horizontal, {
|
|
107
112
|
"$justifyContent": "start",
|
|
108
113
|
children: [_jsx(Button, {
|
|
109
|
-
boxRef:
|
|
114
|
+
boxRef: setReference,
|
|
110
115
|
type: "button",
|
|
111
116
|
view: buttonView,
|
|
112
117
|
size: buttonSize,
|
|
@@ -119,7 +124,7 @@ export const CalendarDropdown = props => {
|
|
|
119
124
|
isOpen: isOpen,
|
|
120
125
|
children: buttonTextCustom ?? buttonText
|
|
121
126
|
}), isOpen && createPortal(_jsx(PopoverContent, {
|
|
122
|
-
ref:
|
|
127
|
+
ref: setFloating,
|
|
123
128
|
style: {
|
|
124
129
|
...floatingStyles,
|
|
125
130
|
zIndex
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { useState } from 'react';
|
|
3
3
|
import { getDisabledRanges } from './getDisabledRanges';
|
|
4
4
|
import { CalendarMonthSlider } from '../../../CalendarMonthSlider/CalendarMonthSlider';
|
|
5
5
|
import { compareStructs } from '../../../helpers';
|
|
@@ -18,17 +18,16 @@ export const CalendarRangePicker = ({
|
|
|
18
18
|
firstDayOfWeek,
|
|
19
19
|
initialVisibleMonth
|
|
20
20
|
}) => {
|
|
21
|
-
const
|
|
22
|
-
if (!startMonthRef.current) {
|
|
21
|
+
const [startMonth] = useState(() => {
|
|
23
22
|
const d = new Date();
|
|
24
|
-
|
|
23
|
+
return initialVisibleMonth ?? value[0] ?? {
|
|
25
24
|
year: d.getFullYear(),
|
|
26
25
|
month: d.getMonth() + 1,
|
|
27
26
|
day: d.getDate()
|
|
28
27
|
};
|
|
29
|
-
}
|
|
28
|
+
});
|
|
30
29
|
return _jsx(CalendarMonthSlider, {
|
|
31
|
-
startMonth:
|
|
30
|
+
startMonth: startMonth,
|
|
32
31
|
visibleCount: visibleCount,
|
|
33
32
|
monthWidth: monthWidth,
|
|
34
33
|
gap: gap,
|
|
@@ -49,7 +49,12 @@ export const DropdownMenu = ({
|
|
|
49
49
|
zIndex: menuZIndex
|
|
50
50
|
});
|
|
51
51
|
const {
|
|
52
|
-
refs
|
|
52
|
+
refs: {
|
|
53
|
+
reference,
|
|
54
|
+
floating,
|
|
55
|
+
setReference,
|
|
56
|
+
setFloating
|
|
57
|
+
},
|
|
53
58
|
floatingStyles
|
|
54
59
|
} = useFloating({
|
|
55
60
|
open: isOpen,
|
|
@@ -70,7 +75,7 @@ export const DropdownMenu = ({
|
|
|
70
75
|
useEffect(() => {
|
|
71
76
|
if (isOpen) {
|
|
72
77
|
const handleClickListener = e => {
|
|
73
|
-
if (!
|
|
78
|
+
if (!floating.current?.contains(e.target) && !reference.current?.contains(e.target)) {
|
|
74
79
|
handleClose();
|
|
75
80
|
}
|
|
76
81
|
};
|
|
@@ -82,17 +87,17 @@ export const DropdownMenu = ({
|
|
|
82
87
|
document.removeEventListener('click', handleClickListener);
|
|
83
88
|
};
|
|
84
89
|
}
|
|
85
|
-
}, [isOpen,
|
|
90
|
+
}, [isOpen, floating, reference, handleClose]);
|
|
86
91
|
useEffect(() => {
|
|
87
|
-
if (isOpen && isScrollable &&
|
|
88
|
-
const activeElement =
|
|
92
|
+
if (isOpen && isScrollable && floating.current) {
|
|
93
|
+
const activeElement = floating.current.querySelector('[data-active="true"]');
|
|
89
94
|
if (activeElement) {
|
|
90
95
|
activeElement.scrollIntoView({
|
|
91
96
|
block: 'nearest'
|
|
92
97
|
});
|
|
93
98
|
}
|
|
94
99
|
}
|
|
95
|
-
}, [isOpen, isScrollable,
|
|
100
|
+
}, [isOpen, isScrollable, floating]);
|
|
96
101
|
return _jsxs(DropdownContext.Provider, {
|
|
97
102
|
value: setIsOpen,
|
|
98
103
|
children: [renderHandler({
|
|
@@ -103,12 +108,12 @@ export const DropdownMenu = ({
|
|
|
103
108
|
setIsOpen(true);
|
|
104
109
|
}
|
|
105
110
|
},
|
|
106
|
-
ref:
|
|
111
|
+
ref: setReference,
|
|
107
112
|
isOpen
|
|
108
113
|
}), isOpen && createPortal(_jsx(DropdownZIndexContext.Provider, {
|
|
109
114
|
value: resolvedZIndex,
|
|
110
115
|
children: _jsx(Place, {
|
|
111
|
-
ref:
|
|
116
|
+
ref: setFloating,
|
|
112
117
|
style: floatingStyles,
|
|
113
118
|
"$color": color,
|
|
114
119
|
"$width": width ?? undefined,
|
|
@@ -39,7 +39,10 @@ export const DropdownMenuSubmenu = ({
|
|
|
39
39
|
const openedByClick = useRef(false);
|
|
40
40
|
const [availableHeight, setAvailableHeight] = useState();
|
|
41
41
|
const {
|
|
42
|
-
refs
|
|
42
|
+
refs: {
|
|
43
|
+
setReference,
|
|
44
|
+
setFloating
|
|
45
|
+
},
|
|
43
46
|
floatingStyles
|
|
44
47
|
} = useFloating({
|
|
45
48
|
strategy: 'fixed',
|
|
@@ -98,7 +101,7 @@ export const DropdownMenuSubmenu = ({
|
|
|
98
101
|
children: _jsxs(DropdownZIndexContext.Provider, {
|
|
99
102
|
value: submenuZIndex,
|
|
100
103
|
children: [_jsx(DropdownMenuItemStyled, {
|
|
101
|
-
ref:
|
|
104
|
+
ref: setReference,
|
|
102
105
|
type: "button",
|
|
103
106
|
"$active": isOpen,
|
|
104
107
|
"$danger": isDanger,
|
|
@@ -122,7 +125,7 @@ export const DropdownMenuSubmenu = ({
|
|
|
122
125
|
}), isOpen && createPortal(_jsx(SubmenuRegistryContext.Provider, {
|
|
123
126
|
value: submenus,
|
|
124
127
|
children: _jsx(Place, {
|
|
125
|
-
ref:
|
|
128
|
+
ref: setFloating,
|
|
126
129
|
style: {
|
|
127
130
|
...floatingStyles,
|
|
128
131
|
maxHeight,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { arrow, autoPlacement, offset, useFloating } from '@floating-ui/react-dom';
|
|
3
3
|
import { isEqual } from 'es-toolkit';
|
|
4
|
-
import { useEffect,
|
|
4
|
+
import { useEffect, useState } from 'react';
|
|
5
5
|
import { Transforms } from 'slate';
|
|
6
6
|
import { Collapse, elementAddListener, Horizontal, usePersistentFunction } from '@pushwoosh/kit-helpers';
|
|
7
7
|
import { FieldBox } from '../FieldBox';
|
|
@@ -36,9 +36,13 @@ export const RichMessageEditor = ({
|
|
|
36
36
|
}) => {
|
|
37
37
|
const [showDrop, setShowDrop] = useState();
|
|
38
38
|
const [isFocused, setIsFocused] = useState(false);
|
|
39
|
-
const
|
|
39
|
+
const [arrowElement, setArrowElement] = useState(null);
|
|
40
40
|
const {
|
|
41
|
-
refs
|
|
41
|
+
refs: {
|
|
42
|
+
reference,
|
|
43
|
+
setReference,
|
|
44
|
+
setFloating
|
|
45
|
+
},
|
|
42
46
|
floatingStyles,
|
|
43
47
|
update,
|
|
44
48
|
middlewareData,
|
|
@@ -48,7 +52,7 @@ export const RichMessageEditor = ({
|
|
|
48
52
|
middleware: [offset(8), autoPlacement({
|
|
49
53
|
allowedPlacements: ['right', 'right-start', 'right-end', 'left', 'left-start', 'left-end']
|
|
50
54
|
}), arrow({
|
|
51
|
-
element:
|
|
55
|
+
element: arrowElement
|
|
52
56
|
})]
|
|
53
57
|
});
|
|
54
58
|
const onSelectionChange = selection => {
|
|
@@ -91,11 +95,11 @@ export const RichMessageEditor = ({
|
|
|
91
95
|
return;
|
|
92
96
|
}
|
|
93
97
|
return elementAddListener(document, ['mousedown', 'touchstart', 'focusin'], event => {
|
|
94
|
-
if (
|
|
98
|
+
if (reference.current instanceof HTMLElement && !reference.current.contains(event.target)) {
|
|
95
99
|
clickAwayHandler();
|
|
96
100
|
}
|
|
97
101
|
});
|
|
98
|
-
}, [clickAwayHandler, isFocused,
|
|
102
|
+
}, [clickAwayHandler, isFocused, reference]);
|
|
99
103
|
return _jsx(SlateEditor, {
|
|
100
104
|
initialValue: initialValue,
|
|
101
105
|
onChange: onChange,
|
|
@@ -104,7 +108,7 @@ export const RichMessageEditor = ({
|
|
|
104
108
|
editor
|
|
105
109
|
}) => _jsxs(FieldBox, {
|
|
106
110
|
title: title,
|
|
107
|
-
boxRef:
|
|
111
|
+
boxRef: setReference,
|
|
108
112
|
error: error,
|
|
109
113
|
actions: _jsx(Collapse, {
|
|
110
114
|
expanded: isFocused,
|
|
@@ -141,7 +145,7 @@ export const RichMessageEditor = ({
|
|
|
141
145
|
}
|
|
142
146
|
}), showDrop && _jsxs(DropArea, {
|
|
143
147
|
style: floatingStyles,
|
|
144
|
-
ref:
|
|
148
|
+
ref: setFloating,
|
|
145
149
|
children: [showDrop.type === 'personalization' && _jsx(DropContent, {
|
|
146
150
|
children: renderDynamicContent?.({
|
|
147
151
|
dc: showDrop.path ? getDcByPath(editor.children, showDrop.path)?.dc : undefined,
|
|
@@ -163,7 +167,7 @@ export const RichMessageEditor = ({
|
|
|
163
167
|
onEmojiSelect: s => editor.insertText(s)
|
|
164
168
|
}), _jsx(Arrow, {
|
|
165
169
|
"$direction": placementToDirection(placement),
|
|
166
|
-
ref:
|
|
170
|
+
ref: setArrowElement,
|
|
167
171
|
style: {
|
|
168
172
|
left: middlewareData.arrow?.x,
|
|
169
173
|
top: middlewareData.arrow?.y
|
package/Tooltip/Tooltip.js
CHANGED
|
@@ -44,7 +44,8 @@ export function Tooltip({
|
|
|
44
44
|
isOpen
|
|
45
45
|
});
|
|
46
46
|
const {
|
|
47
|
-
setReference
|
|
47
|
+
setReference,
|
|
48
|
+
setFloating
|
|
48
49
|
} = refs;
|
|
49
50
|
const originalRef = isValidElement(children) ? children.ref : undefined;
|
|
50
51
|
const setChildRef = useCallback(node => {
|
|
@@ -86,7 +87,7 @@ export function Tooltip({
|
|
|
86
87
|
}) : children ?? null;
|
|
87
88
|
return _jsxs(_Fragment, {
|
|
88
89
|
children: [anchor, isOpen && referenceEl && createPortal(_jsxs(TooltipBox, {
|
|
89
|
-
ref:
|
|
90
|
+
ref: setFloating,
|
|
90
91
|
style: {
|
|
91
92
|
...floatingStyles,
|
|
92
93
|
zIndex
|
|
@@ -21,7 +21,7 @@ export declare function useTooltipPosition({ position, offset: offsetProp, arrow
|
|
|
21
21
|
};
|
|
22
22
|
floatingStyles: CSSProperties;
|
|
23
23
|
placement: import("@floating-ui/react-dom").Placement;
|
|
24
|
-
arrowRef: import("react").
|
|
24
|
+
arrowRef: import("react").Dispatch<import("react").SetStateAction<HTMLDivElement | null>>;
|
|
25
25
|
arrowStyles: CSSProperties;
|
|
26
26
|
};
|
|
27
27
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { arrow, autoUpdate, flip, offset, shift, useFloating } from '@floating-ui/react-dom';
|
|
2
|
-
import {
|
|
2
|
+
import { useState } from 'react';
|
|
3
3
|
import { resolveArrowPadding } from './helpers';
|
|
4
4
|
import { TooltipPositionToFloatingPlacementMap, TooltipPositionToOffsetMap } from './maps';
|
|
5
5
|
const ArrowStaticSideMap = {
|
|
@@ -20,7 +20,7 @@ export function useTooltipPosition({
|
|
|
20
20
|
arrowOffset,
|
|
21
21
|
isOpen
|
|
22
22
|
}) {
|
|
23
|
-
const
|
|
23
|
+
const [arrowElement, setArrowElement] = useState(null);
|
|
24
24
|
const [skidding, distance] = offsetProp ?? TooltipPositionToOffsetMap[position];
|
|
25
25
|
const arrowPadding = resolveArrowPadding(arrowOffset);
|
|
26
26
|
const {
|
|
@@ -38,7 +38,7 @@ export function useTooltipPosition({
|
|
|
38
38
|
}), flip(), shift({
|
|
39
39
|
padding: 8
|
|
40
40
|
}), arrow({
|
|
41
|
-
element:
|
|
41
|
+
element: arrowElement,
|
|
42
42
|
padding: arrowPadding
|
|
43
43
|
})],
|
|
44
44
|
whileElementsMounted: autoUpdate
|
|
@@ -57,7 +57,7 @@ export function useTooltipPosition({
|
|
|
57
57
|
refs,
|
|
58
58
|
floatingStyles,
|
|
59
59
|
placement,
|
|
60
|
-
arrowRef,
|
|
60
|
+
arrowRef: setArrowElement,
|
|
61
61
|
arrowStyles
|
|
62
62
|
};
|
|
63
63
|
}
|
package/hooks/useLayer.js
CHANGED
|
@@ -100,9 +100,11 @@ export function useLayer({
|
|
|
100
100
|
}) {
|
|
101
101
|
const id = useId();
|
|
102
102
|
const onCloseRef = useRef(onClose);
|
|
103
|
-
onCloseRef.current = onClose;
|
|
104
103
|
const zIndexRef = useRef(zIndex);
|
|
105
|
-
|
|
104
|
+
useLayoutEffect(() => {
|
|
105
|
+
onCloseRef.current = onClose;
|
|
106
|
+
zIndexRef.current = zIndex;
|
|
107
|
+
});
|
|
106
108
|
useLayoutEffect(() => {
|
|
107
109
|
if (!isOpen) {
|
|
108
110
|
return undefined;
|
package/hooks/useThemeName.js
CHANGED
|
@@ -11,7 +11,7 @@ function readThemeName(element) {
|
|
|
11
11
|
* @param ref - element inside the theme scope, so a light island wins over the document theme
|
|
12
12
|
* @param isEnabled - pass `false` when the caller already knows the theme and needs no observer */
|
|
13
13
|
export function useThemeName(ref, isEnabled = true) {
|
|
14
|
-
const [themeName, setThemeName] = useState(() => readThemeName(
|
|
14
|
+
const [themeName, setThemeName] = useState(() => readThemeName(null));
|
|
15
15
|
useLayoutEffect(() => {
|
|
16
16
|
if (!isEnabled) {
|
|
17
17
|
return undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pushwoosh/dumb-components",
|
|
3
|
-
"version": "4.7.
|
|
3
|
+
"version": "4.7.2",
|
|
4
4
|
"description": "React components to build Pushwoosh products",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "index.js",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"@floating-ui/react-dom": "^2.1.2",
|
|
38
38
|
"@lezer/highlight": "^1.2.1",
|
|
39
39
|
"@pushwoosh/kit-constants": "^3.0.0",
|
|
40
|
-
"@pushwoosh/kit-helpers": "^4.16.
|
|
40
|
+
"@pushwoosh/kit-helpers": "^4.16.1",
|
|
41
41
|
"@pushwoosh/kit-icons": "^2.3.15",
|
|
42
42
|
"@pushwoosh/kit-typography": "^2.0.0",
|
|
43
43
|
"@tippyjs/react": "^4.2.6",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
1
|
+
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
2
2
|
import { DEFAULT_DEBOUNCE_MS } from './constants';
|
|
3
3
|
import { useDebouncedValue } from './useDebouncedValue';
|
|
4
4
|
/**
|
|
@@ -20,7 +20,9 @@ export function useAsyncItems({
|
|
|
20
20
|
});
|
|
21
21
|
const debouncedQuery = useDebouncedValue(query, debounceMs);
|
|
22
22
|
const loadItemsRef = useRef(loadItems);
|
|
23
|
-
|
|
23
|
+
useLayoutEffect(() => {
|
|
24
|
+
loadItemsRef.current = loadItems;
|
|
25
|
+
});
|
|
24
26
|
const sessionRef = useRef(0);
|
|
25
27
|
const pageRef = useRef(0);
|
|
26
28
|
const queryRef = useRef('');
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEffect, useRef } from 'react';
|
|
1
|
+
import { useEffect, useEffectEvent, useRef } from 'react';
|
|
2
2
|
/**
|
|
3
3
|
* Side effects tied to a Combobox field's open state: optional autofocus on mount
|
|
4
4
|
* and firing `onClose` when the field closes.
|
|
@@ -11,11 +11,10 @@ export function useFieldOpenEffects({
|
|
|
11
11
|
disabled,
|
|
12
12
|
inputRef
|
|
13
13
|
}) {
|
|
14
|
-
const
|
|
15
|
-
onCloseRef.current = onClose;
|
|
14
|
+
const onCloseEvent = useEffectEvent(() => onClose?.());
|
|
16
15
|
const wasOpenRef = useRef(isOpen);
|
|
17
16
|
useEffect(() => {
|
|
18
|
-
if (wasOpenRef.current && !isOpen)
|
|
17
|
+
if (wasOpenRef.current && !isOpen) onCloseEvent();
|
|
19
18
|
wasOpenRef.current = isOpen;
|
|
20
19
|
}, [isOpen]);
|
|
21
20
|
const didAutoFocusRef = useRef(false);
|