@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.
@@ -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([refs.reference, refs.floating], () => {
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: refs.setReference,
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: refs.setFloating,
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 { useRef } from 'react';
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 startMonthRef = useRef(undefined);
22
- if (!startMonthRef.current) {
21
+ const [startMonth] = useState(() => {
23
22
  const d = new Date();
24
- startMonthRef.current = initialVisibleMonth ?? value[0] ?? {
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: startMonthRef.current,
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 (!refs.floating.current?.contains(e.target) && !refs.reference.current?.contains(e.target)) {
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, refs.floating, refs.reference, handleClose]);
90
+ }, [isOpen, floating, reference, handleClose]);
86
91
  useEffect(() => {
87
- if (isOpen && isScrollable && refs.floating.current) {
88
- const activeElement = refs.floating.current.querySelector('[data-active="true"]');
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, refs.floating]);
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: refs.setReference,
111
+ ref: setReference,
107
112
  isOpen
108
113
  }), isOpen && createPortal(_jsx(DropdownZIndexContext.Provider, {
109
114
  value: resolvedZIndex,
110
115
  children: _jsx(Place, {
111
- ref: refs.setFloating,
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: refs.setReference,
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: refs.setFloating,
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, useRef, useState } from 'react';
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 arrowRef = useRef(null);
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: arrowRef
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 (refs.reference.current instanceof HTMLElement && !refs.reference.current.contains(event.target)) {
98
+ if (reference.current instanceof HTMLElement && !reference.current.contains(event.target)) {
95
99
  clickAwayHandler();
96
100
  }
97
101
  });
98
- }, [clickAwayHandler, isFocused, refs.reference]);
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: refs.setReference,
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: refs.setFloating,
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: arrowRef,
170
+ ref: setArrowElement,
167
171
  style: {
168
172
  left: middlewareData.arrow?.x,
169
173
  top: middlewareData.arrow?.y
@@ -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: refs.setFloating,
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").RefObject<HTMLDivElement | null>;
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 { useRef } from 'react';
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 arrowRef = useRef(null);
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: arrowRef,
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
- zIndexRef.current = zIndex;
104
+ useLayoutEffect(() => {
105
+ onCloseRef.current = onClose;
106
+ zIndexRef.current = zIndex;
107
+ });
106
108
  useLayoutEffect(() => {
107
109
  if (!isOpen) {
108
110
  return undefined;
@@ -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(ref?.current ?? null));
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.0",
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.0",
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
- loadItemsRef.current = loadItems;
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 onCloseRef = useRef(onClose);
15
- onCloseRef.current = onClose;
14
+ const onCloseEvent = useEffectEvent(() => onClose?.());
16
15
  const wasOpenRef = useRef(isOpen);
17
16
  useEffect(() => {
18
- if (wasOpenRef.current && !isOpen) onCloseRef.current?.();
17
+ if (wasOpenRef.current && !isOpen) onCloseEvent();
19
18
  wasOpenRef.current = isOpen;
20
19
  }, [isOpen]);
21
20
  const didAutoFocusRef = useRef(false);