@rescui/tooltip 0.9.9-RUI-247-Make-packets-react-19-ready-c06b3c96.4 → 0.9.9-RUI-247-Make-packets-react-19-ready-f91b52ef.16

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/lib/index.css CHANGED
@@ -1,10 +1,10 @@
1
- ._tooltip_1cv1efi_5{
1
+ ._tooltip_1kpgvke_5{
2
2
  position:relative;
3
3
  }
4
- ._closing_1cv1efi_9{
4
+ ._closing_1kpgvke_9{
5
5
  pointer-events:none;
6
6
  }
7
- ._content_1cv1efi_13{
7
+ ._content_1kpgvke_13{
8
8
  --rs-theme-dark:1;
9
9
  --_rs-tooltip-border-width:1px;
10
10
 
@@ -75,33 +75,33 @@
75
75
  transition:opacity 300ms, transform 300ms;
76
76
  transform:translate(0, 0);
77
77
  }
78
- [data-real-placement='top-end'] ._content_1cv1efi_13,
79
- [data-real-placement='bottom-end'] ._content_1cv1efi_13{
78
+ [data-popper-placement='top-end'] ._content_1kpgvke_13,
79
+ [data-popper-placement='bottom-end'] ._content_1kpgvke_13{
80
80
  margin-right:0;
81
81
  }
82
- [data-real-placement='top-start'] ._content_1cv1efi_13,
83
- [data-real-placement='bottom-start'] ._content_1cv1efi_13{
82
+ [data-popper-placement='top-start'] ._content_1kpgvke_13,
83
+ [data-popper-placement='bottom-start'] ._content_1kpgvke_13{
84
84
  margin-left:0;
85
85
  }
86
- [data-real-placement='left-end'] ._content_1cv1efi_13,
87
- [data-real-placement='right-end'] ._content_1cv1efi_13{
86
+ [data-popper-placement='left-end'] ._content_1kpgvke_13,
87
+ [data-popper-placement='right-end'] ._content_1kpgvke_13{
88
88
  margin-bottom:0;
89
89
  }
90
- [data-real-placement='left-start'] ._content_1cv1efi_13,
91
- [data-real-placement='right-start'] ._content_1cv1efi_13{
90
+ [data-popper-placement='left-start'] ._content_1kpgvke_13,
91
+ [data-popper-placement='right-start'] ._content_1kpgvke_13{
92
92
  margin-top:0;
93
93
  }
94
- ._initial_1cv1efi_54 ._content_1cv1efi_13{
94
+ ._initial_1kpgvke_54 ._content_1kpgvke_13{
95
95
  transition:none;
96
96
  }
97
- ._closing_1cv1efi_9 ._content_1cv1efi_13{
97
+ ._closing_1kpgvke_9 ._content_1kpgvke_13{
98
98
  transition-duration:200ms, 200ms;
99
99
  }
100
- ._initial_1cv1efi_54 ._content_1cv1efi_13,
101
- ._closing_1cv1efi_9 ._content_1cv1efi_13{
100
+ ._initial_1kpgvke_54 ._content_1kpgvke_13,
101
+ ._closing_1kpgvke_9 ._content_1kpgvke_13{
102
102
  opacity:0;
103
103
  }
104
- ._outerThemeLight_1cv1efi_68 ._content_1cv1efi_13{
104
+ ._outerThemeLight_1kpgvke_68 ._content_1kpgvke_13{
105
105
  --rs-color-primary-dark-theme:var(--rs-color-primary-light-theme);
106
106
  --rs-color-primary-dim-dark-theme:var(--rs-color-primary-dim-light-theme);
107
107
  --rs-color-primary-fog-dark-theme:var(--rs-color-primary-fog-light-theme);
@@ -112,7 +112,7 @@
112
112
  --rs-color-primary-t-fog-light-theme
113
113
  );
114
114
  }
115
- ._outerThemeDark_1cv1efi_81 ._content_1cv1efi_13{
115
+ ._outerThemeDark_1kpgvke_81 ._content_1kpgvke_13{
116
116
  --rs-color-primary-light-theme:var(--rs-color-primary-dark-theme);
117
117
  --rs-color-primary-dim-light-theme:var(--rs-color-primary-dim-dark-theme);
118
118
  --rs-color-primary-fog-light-theme:var(--rs-color-primary-fog-dark-theme);
@@ -123,20 +123,20 @@
123
123
  --rs-color-primary-t-fog-dark-theme
124
124
  );
125
125
  }
126
- ._initial_1cv1efi_54[data-real-placement^='top'] ._content_1cv1efi_13, ._closing_1cv1efi_9[data-real-placement^='top'] ._content_1cv1efi_13{
126
+ ._initial_1kpgvke_54[data-popper-placement^='top'] ._content_1kpgvke_13, ._closing_1kpgvke_9[data-popper-placement^='top'] ._content_1kpgvke_13{
127
127
  transform:translate(0, 10px);
128
128
  }
129
- ._initial_1cv1efi_54[data-real-placement^='right'] ._content_1cv1efi_13, ._closing_1cv1efi_9[data-real-placement^='right'] ._content_1cv1efi_13{
129
+ ._initial_1kpgvke_54[data-popper-placement^='right'] ._content_1kpgvke_13, ._closing_1kpgvke_9[data-popper-placement^='right'] ._content_1kpgvke_13{
130
130
  transform:translate(-10px, 0);
131
131
  }
132
- ._initial_1cv1efi_54[data-real-placement^='bottom'] ._content_1cv1efi_13, ._closing_1cv1efi_9[data-real-placement^='bottom'] ._content_1cv1efi_13{
132
+ ._initial_1kpgvke_54[data-popper-placement^='bottom'] ._content_1kpgvke_13, ._closing_1kpgvke_9[data-popper-placement^='bottom'] ._content_1kpgvke_13{
133
133
  transform:translate(0, -10px);
134
134
  }
135
- ._initial_1cv1efi_54[data-real-placement^='left'] ._content_1cv1efi_13, ._closing_1cv1efi_9[data-real-placement^='left'] ._content_1cv1efi_13{
135
+ ._initial_1kpgvke_54[data-popper-placement^='left'] ._content_1kpgvke_13, ._closing_1kpgvke_9[data-popper-placement^='left'] ._content_1kpgvke_13{
136
136
  transform:translate(10px, 0);
137
137
  }
138
- ._trigger_1cv1efi_113:focus-visible,
139
- ._trigger_1cv1efi_113:focus[data-focus-method='key']{
138
+ ._trigger_1kpgvke_113:focus-visible,
139
+ ._trigger_1kpgvke_113:focus[data-focus-method='key']{
140
140
  outline:none;
141
141
 
142
142
  box-shadow:var(--rs-color-primary-t-dim-light-theme) 0 0 0 4px;
package/lib/tooltip.js CHANGED
@@ -5,14 +5,12 @@ import { Element, ForwardRef, typeOf } from 'react-is';
5
5
  import cn from 'classnames';
6
6
  import PropTypes from 'prop-types';
7
7
  import ReactDOM from 'react-dom';
8
- import { Manager, Reference, Popper } from 'react-popper';
9
- import { ThemeContext, LayeringConsumer, ThemeProvider } from '@rescui/ui-contexts';
10
- import styles from './index.p.module.css.js';
8
+ import { usePopper } from 'react-popper';
9
+ import { useLayeringContext, ThemeContext, ThemeProvider } from '@rescui/ui-contexts';
10
+ import styles from './tooltip.p.module.css.js';
11
11
  import { useTooltipState, TOOLTIP_STATES } from './use-tooltip-state.js';
12
12
  import { extractThemeFromCss, extractPrimaryColors } from './css-vars-utils.js';
13
- const HIDE_TIMEOUT = 500; // it should in sync with the transition-duration css-property
14
-
15
- const CLOSING_TIMEOUT = 300;
13
+ const HIDE_TIMEOUT = 500;
16
14
 
17
15
  const Portal = _ref => {
18
16
  let {
@@ -122,14 +120,27 @@ const Tooltip = _ref3 => {
122
120
  disableHideDelay,
123
121
  renderBesideTrigger = false
124
122
  } = _ref3;
123
+ const {
124
+ tooltipZIndex
125
+ } = useLayeringContext();
126
+ const [popperRef, setPopperRef] = useState(null);
125
127
  const [triggerRef, setTriggerRef] = useState(null);
126
- const isControlled = typeof isVisibleFromProps !== 'undefined';
127
128
  const [isVisibleState, setIsVisibleState] = useState(false);
128
129
  const [isTooltipHovered, setIsTooltipHovered] = useState(false);
129
130
  const schedulePopperUpdateRef = useRef(null);
130
131
  const contentRef = useRef(null);
131
132
  const hideTimeoutRef = useRef(null);
132
- const isVisible = isControlled ? isVisibleFromProps : isVisibleState;
133
+ const isControlled = typeof isVisibleFromProps !== 'undefined';
134
+ let isVisible = isControlled ? isVisibleFromProps : isVisibleState; // We set isVisible this way to avoid hydration issue due to
135
+ // the Portal to document.body which does not exist on the server.
136
+ // So even if isVisible prop is used, the tooltip will not render on the server, and
137
+ // it's the same on the first client render, so there is no hydration issue.
138
+
139
+ const [isFirstRender, setIsFirstRender] = useState(true);
140
+ useEffect(() => {
141
+ setIsFirstRender(false);
142
+ }, []);
143
+ isVisible = isFirstRender && !renderBesideTrigger ? false : isVisible;
133
144
  const isOpen = isVisible || isTooltipHovered;
134
145
  const PortalResolved = renderBesideTrigger ? React.Fragment : Portal;
135
146
  useEffect(() => {
@@ -157,9 +168,9 @@ const Tooltip = _ref3 => {
157
168
  }
158
169
  };
159
170
 
160
- const tooltipState = useTooltipState(isOpen, CLOSING_TIMEOUT);
171
+ const [handleAnimationEnd, tooltipState] = useTooltipState(isOpen);
161
172
  const isClosing = tooltipState === TOOLTIP_STATES.CLOSING;
162
- const isExists = tooltipState !== TOOLTIP_STATES.CLOSED; // a state to toggle the starting transition
173
+ const isExists = tooltipState !== TOOLTIP_STATES.CLOSE; // a state to toggle the starting transition
163
174
 
164
175
  const [isInitial, setIsInitial] = useState(true); // reset the initial flag when the closing transition ends and the state switches to CLOSED
165
176
 
@@ -198,86 +209,75 @@ const Tooltip = _ref3 => {
198
209
  noProvider
199
210
  } = useContext(ThemeContext);
200
211
  const theme = noProvider ? themeFromCss : themeFromContext;
201
- return /*#__PURE__*/React.createElement(LayeringConsumer, null, _ref5 => {
212
+ const calcOffset = useCallback(_ref5 => {
202
213
  let {
203
- tooltipZIndex
214
+ placement: offsetPlacement
204
215
  } = _ref5;
205
- return /*#__PURE__*/React.createElement(Manager, null, /*#__PURE__*/React.createElement(Reference, null, _ref6 => {
206
- let {
207
- ref
208
- } = _ref6;
209
- return /*#__PURE__*/React.createElement(TriggerRenderer, {
210
- ref: ref,
211
- setTriggerRef: setTriggerRef,
212
- targetComponent: targetComponent,
213
- isControlled: isControlled,
214
- handleMouseEnterTarget: handleMouseEnterTarget,
215
- handleMouseLeaveTarget: handleMouseLeaveTarget
216
- }, children);
217
- }), tooltipShouldBeRendered && /*#__PURE__*/React.createElement(PortalResolved, null, /*#__PURE__*/React.createElement(Popper, {
218
- placement: placement,
219
- modifiers: [// the modifier to trigger starting animation
220
- {
221
- name: 'disableInitialFlag',
222
- enabled: true,
223
- phase: 'afterWrite',
224
- fn: disableInitialFlag,
225
- requires: []
226
- }, {
227
- name: 'flip',
228
- options: {
229
- fallbackPlacements
230
- }
231
- }, {
232
- name: 'offset',
233
- options: {
234
- offset: _ref7 => {
235
- let {
236
- placement: offsetPlacement
237
- } = _ref7;
238
216
 
239
- if (_includesInstanceProperty(offsetPlacement).call(offsetPlacement, 'left') || _includesInstanceProperty(offsetPlacement).call(offsetPlacement, 'right')) {
240
- return [0, sparse ? 16 : 8];
241
- } else {
242
- return [0, sparse ? 12 : 8];
243
- }
244
- }
245
- }
246
- }, ...(modifiers || [])]
247
- }, _ref8 => {
248
- let {
249
- ref,
250
- style,
251
- update,
252
- placement: realPlacement
253
- } = _ref8;
254
- schedulePopperUpdateRef.current = update;
255
- return /*#__PURE__*/React.createElement("span", {
256
- className: cn(styles.tooltip, isInitial && styles.initial, isClosing && styles.closing, OUTER_THEME_STYLES[theme], className),
257
- ref: ref,
258
- style: { ...style,
259
- ...primaryColors,
260
- zIndex: tooltipZIndex
261
- },
262
- onMouseEnter: () => setIsTooltipHovered(true),
263
- onMouseLeave: () => {
264
- setIsVisibleState(false);
265
- setIsTooltipHovered(false);
266
- },
267
- "data-placement": placement,
268
- "data-real-placement": realPlacement,
269
- "data-test": "tooltip"
270
- }, /*#__PURE__*/React.createElement(ThemeProvider, {
271
- theme: "dark",
272
- ignoreThemeValueForCSSApi: noProvider
273
- }, /*#__PURE__*/React.createElement("div", {
274
- className: cn(styles.content),
275
- onBlur: handleMouseLeaveTarget,
276
- onFocus: handleMouseEnterTarget,
277
- ref: contentRef
278
- }, content)));
279
- })));
217
+ if (_includesInstanceProperty(offsetPlacement).call(offsetPlacement, 'left') || _includesInstanceProperty(offsetPlacement).call(offsetPlacement, 'right')) {
218
+ return [0, sparse ? 16 : 8];
219
+ } else {
220
+ return [0, sparse ? 12 : 8];
221
+ }
222
+ }, [sparse]);
223
+ const {
224
+ styles: popperStyles,
225
+ attributes,
226
+ update
227
+ } = usePopper(triggerRef, popperRef, {
228
+ placement,
229
+ modifiers: [// the modifier to trigger starting animation
230
+ {
231
+ name: 'disableInitialFlag',
232
+ enabled: true,
233
+ phase: 'afterWrite',
234
+ fn: disableInitialFlag,
235
+ requires: []
236
+ }, {
237
+ name: 'flip',
238
+ options: {
239
+ fallbackPlacements
240
+ }
241
+ }, {
242
+ name: 'offset',
243
+ options: {
244
+ offset: calcOffset
245
+ }
246
+ }, ...(modifiers || [])]
280
247
  });
248
+ schedulePopperUpdateRef.current = update;
249
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(TriggerRenderer, {
250
+ setTriggerRef: setTriggerRef,
251
+ targetComponent: targetComponent,
252
+ isControlled: isControlled,
253
+ handleMouseEnterTarget: handleMouseEnterTarget,
254
+ handleMouseLeaveTarget: handleMouseLeaveTarget
255
+ }, children), tooltipShouldBeRendered && /*#__PURE__*/React.createElement(PortalResolved, null, /*#__PURE__*/React.createElement("span", {
256
+ className: cn(styles.tooltip, isInitial && styles.initial, isClosing && styles.closing, OUTER_THEME_STYLES[theme], className),
257
+ ref: setPopperRef,
258
+ style: { ...popperStyles.popper,
259
+ ...primaryColors,
260
+ zIndex: tooltipZIndex
261
+ },
262
+ onMouseEnter: () => setIsTooltipHovered(true),
263
+ onMouseLeave: () => {
264
+ setIsVisibleState(false);
265
+ setIsTooltipHovered(false);
266
+ },
267
+ "data-placement": placement,
268
+ "data-test": "tooltip",
269
+ ...attributes.popper
270
+ }, /*#__PURE__*/React.createElement(ThemeProvider, {
271
+ theme: "dark",
272
+ ignoreThemeValueForCSSApi: noProvider
273
+ }, /*#__PURE__*/React.createElement("div", {
274
+ className: cn(styles.content),
275
+ onBlur: handleMouseLeaveTarget,
276
+ onFocus: handleMouseEnterTarget,
277
+ onTransitionEnd: handleAnimationEnd,
278
+ onAnimationEnd: handleAnimationEnd,
279
+ ref: contentRef
280
+ }, content)))));
281
281
  };
282
282
 
283
283
  Tooltip.propTypes = {
@@ -0,0 +1,10 @@
1
+ var styles = {
2
+ "tooltip": "_tooltip_1kpgvke_5",
3
+ "closing": "_closing_1kpgvke_9",
4
+ "content": "_content_1kpgvke_13",
5
+ "initial": "_initial_1kpgvke_54",
6
+ "outerThemeLight": "_outerThemeLight_1kpgvke_68",
7
+ "outerThemeDark": "_outerThemeDark_1kpgvke_81",
8
+ "trigger": "_trigger_1kpgvke_113"
9
+ };
10
+ export { styles as default };
@@ -1,6 +1,7 @@
1
1
  export declare enum TOOLTIP_STATES {
2
+ OPENING = "OPENING",
2
3
  OPEN = "OPEN",
3
4
  CLOSING = "CLOSING",
4
- CLOSED = "CLOSED"
5
+ CLOSE = "CLOSE"
5
6
  }
6
- export declare function useTooltipState(isOpen: boolean, transitionDuration?: number): TOOLTIP_STATES;
7
+ export declare function useTooltipState(isOpen: boolean): [() => void, TOOLTIP_STATES];
@@ -1,57 +1,36 @@
1
1
  "use client";
2
- import { useState, useEffect } from 'react';
2
+ import { useState, useRef, useCallback } from 'react';
3
3
  var TOOLTIP_STATES;
4
4
 
5
5
  (function (TOOLTIP_STATES) {
6
+ TOOLTIP_STATES["OPENING"] = "OPENING";
6
7
  TOOLTIP_STATES["OPEN"] = "OPEN";
7
8
  TOOLTIP_STATES["CLOSING"] = "CLOSING";
8
- TOOLTIP_STATES["CLOSED"] = "CLOSED";
9
+ TOOLTIP_STATES["CLOSE"] = "CLOSE";
9
10
  })(TOOLTIP_STATES || (TOOLTIP_STATES = {}));
10
11
 
11
12
  function useTooltipState(isOpen) {
12
- let transitionDuration = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
13
- const [state, setState] = useState(TOOLTIP_STATES.CLOSED);
14
- useEffect(() => {
15
- if (isOpen) {
16
- // set tooltip state to OPEN when it should be open, but the current state is closing or already closed
17
- setState(curState => {
18
- if (curState === TOOLTIP_STATES.CLOSING || curState === TOOLTIP_STATES.CLOSED) {
19
- return TOOLTIP_STATES.OPEN;
20
- } else {
21
- return curState;
22
- }
23
- });
24
- }
25
-
26
- if (!isOpen) {
27
- // if tooltip should not be open, but actually open, start the closing process
28
- setState(curState => {
29
- if (curState === TOOLTIP_STATES.OPEN) {
30
- return TOOLTIP_STATES.CLOSING;
31
- }
13
+ const [, setDummyState] = useState(false);
14
+ const stateRef = useRef(TOOLTIP_STATES.CLOSE);
15
+ const onAnimationEnd = useCallback(() => {
16
+ if ((stateRef.current === TOOLTIP_STATES.CLOSING || stateRef.current === TOOLTIP_STATES.OPENING) && !isOpen) {
17
+ stateRef.current = TOOLTIP_STATES.CLOSE; //force rerender
32
18
 
33
- return curState;
34
- }); // by the time the transition is finished, set state from closing to closed
35
- // if by any means at that moment state is not closing (but open or already closed), do nothing
19
+ setDummyState(s => !s);
20
+ } else if (stateRef.current === TOOLTIP_STATES.OPENING && isOpen) {
21
+ stateRef.current = TOOLTIP_STATES.OPEN; //force rerender
36
22
 
37
- const timeoutId = setTimeout(() => {
38
- setState(curState => {
39
- if (curState === TOOLTIP_STATES.CLOSING) {
40
- return TOOLTIP_STATES.CLOSED;
41
- }
42
-
43
- return curState;
44
- });
45
- }, transitionDuration);
46
- return () => {
47
- clearTimeout(timeoutId);
48
- };
49
- } // eslint-disable-next-line @typescript-eslint/no-empty-function
23
+ setDummyState(s => !s);
24
+ }
25
+ }, [isOpen]);
50
26
 
27
+ if (isOpen && stateRef.current !== TOOLTIP_STATES.OPEN) {
28
+ stateRef.current = TOOLTIP_STATES.OPENING;
29
+ } else if (stateRef.current === TOOLTIP_STATES.OPEN && !isOpen) {
30
+ stateRef.current = TOOLTIP_STATES.CLOSING;
31
+ }
51
32
 
52
- return () => {};
53
- }, [transitionDuration, isOpen]);
54
- return state;
33
+ return [onAnimationEnd, stateRef.current];
55
34
  }
56
35
 
57
36
  export { TOOLTIP_STATES, useTooltipState };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rescui/tooltip",
3
- "version": "0.9.9-RUI-247-Make-packets-react-19-ready-c06b3c96.4+c06b3c96",
3
+ "version": "0.9.9-RUI-247-Make-packets-react-19-ready-f91b52ef.16+f91b52ef",
4
4
  "description": "",
5
5
  "license": "Apache-2.0",
6
6
  "author": "JetBrains",
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "dependencies": {
18
18
  "@babel/runtime-corejs3": "^7.26.0",
19
- "@popperjs/core": "^2.9.2",
19
+ "@popperjs/core": "^2.11.8",
20
20
  "classnames": "^2.2.6",
21
21
  "react-is": "^17.0.2",
22
22
  "react-popper": "^2.2.5"
@@ -28,15 +28,15 @@
28
28
  "react-dom": ">=16.8.0 <20"
29
29
  },
30
30
  "devDependencies": {
31
- "@rescui/colors": "0.2.10-RUI-247-Make-packets-react-19-ready-c06b3c96.4+c06b3c96",
32
- "@rescui/icons": "1.2.1-RUI-247-Make-packets-react-19-ready-c06b3c96.4+c06b3c96",
31
+ "@rescui/colors": "0.2.10-RUI-247-Make-packets-react-19-ready-f91b52ef.16+f91b52ef",
32
+ "@rescui/icons": "1.2.1-RUI-247-Make-packets-react-19-ready-f91b52ef.16+f91b52ef",
33
33
  "@rescui/scripts": "0.5.0",
34
- "@rescui/typography": "0.23.3-RUI-247-Make-packets-react-19-ready-c06b3c96.4+c06b3c96",
34
+ "@rescui/typography": "0.23.3-RUI-247-Make-packets-react-19-ready-f91b52ef.16+f91b52ef",
35
35
  "@types/react-is": "^17.0.3"
36
36
  },
37
37
  "scripts": {
38
38
  "build": "rescui-scripts build"
39
39
  },
40
40
  "nx": {},
41
- "gitHead": "c06b3c969a1e66ca4bb7a6b7f3f2e77746682f13"
41
+ "gitHead": "f91b52ef45b5e50ebcb7063345703b37fb950f5c"
42
42
  }
@@ -1,10 +0,0 @@
1
- var styles = {
2
- "tooltip": "_tooltip_1cv1efi_5",
3
- "closing": "_closing_1cv1efi_9",
4
- "content": "_content_1cv1efi_13",
5
- "initial": "_initial_1cv1efi_54",
6
- "outerThemeLight": "_outerThemeLight_1cv1efi_68",
7
- "outerThemeDark": "_outerThemeDark_1cv1efi_81",
8
- "trigger": "_trigger_1cv1efi_113"
9
- };
10
- export { styles as default };