@trackunit/react-components 4.0.0 → 4.0.3

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/index.cjs.js CHANGED
@@ -2251,12 +2251,25 @@ const FloatingArrowContainer = ({ arrowRef, mode = "dark", }) => {
2251
2251
  * @param {TooltipProps} props - The props for the Tooltip component
2252
2252
  * @returns {ReactElement} Tooltip component
2253
2253
  */
2254
- const Tooltip = ({ children, "data-testid": dataTestId, disabled = false, label, placement = "auto", mode = "dark", iconProps, id, style, delayed = false, interactable = true, ref, ...rest }) => {
2254
+ const Tooltip = ({ children, "data-testid": dataTestId, disabled = false, label, placement = "auto", mode = "dark", iconProps, id, style, delayed = false, interactable = true, "data-state": dataState, ref, ...rest }) => {
2255
2255
  const [isOpen, setIsOpen] = react.useState(false);
2256
+ // PopoverTrigger marks the element that opened a menu or popover with data-state="open".
2257
+ // That state lands on this tooltip when it is the trigger, or on the child when a parent
2258
+ // such as IconButton forwards it. Keep the tooltip dismissed so it cannot sit on top of the popup.
2259
+ const triggerHasOpenPopup = dataState === "open" ||
2260
+ (react.isValidElement(children) && children.props["data-state"] === "open");
2261
+ const tooltipSuppressed = disabled || triggerHasOpenPopup;
2262
+ // Drop a hover-open in the same render that the trigger's popup opens. A later
2263
+ // effect would commit the tooltip once more and can restore it after the pointer
2264
+ // has already left. Disabled is left alone: a hover that starts while disabled
2265
+ // should still appear once the tooltip is enabled again.
2266
+ if (triggerHasOpenPopup && isOpen) {
2267
+ setIsOpen(false);
2268
+ }
2256
2269
  const arrowRef = react.useRef(null);
2257
2270
  const { refs, floatingStyles, context } = react$1.useFloating({
2258
2271
  placement: placement === "auto" ? "bottom" : placement,
2259
- open: disabled ? false : isOpen,
2272
+ open: tooltipSuppressed ? false : isOpen,
2260
2273
  onOpenChange: setIsOpen,
2261
2274
  middleware: [
2262
2275
  react$1.offset(8),
@@ -2275,7 +2288,7 @@ const Tooltip = ({ children, "data-testid": dataTestId, disabled = false, label,
2275
2288
  const wrappedChildren = react.useMemo(() => {
2276
2289
  return jsxRuntime.jsx(reactSlot.Slot, { children: children });
2277
2290
  }, [children]);
2278
- return (jsxRuntime.jsxs(Popover, { activation: { click: false, hover: { delayed, interactable } }, className: cvaTooltipPopover(), "data-testid": dataTestId, id: id, onOpenStateChange: setIsOpen, placement: placement === "auto" ? "bottom" : placement, children: [jsxRuntime.jsx(PopoverTrigger, { ...rest, "data-testid": dataTestId ? `${dataTestId}-trigger` : null, ref: mergedRef, style: style, children: children === undefined ? (jsxRuntime.jsx(Icon, { className: cvaTooltipIcon({ color: mode }), "data-testid": dataTestId ? `${dataTestId}-icon` : undefined, name: "QuestionMarkCircle", size: "small", ...iconProps })) : (wrappedChildren) }), isMounted ? (jsxRuntime.jsx("div", { ref: refs.setFloating, style: floatingStyles, children: jsxRuntime.jsx(PopoverContent, { initialFocus: -1, returnFocus: false, children: jsxRuntime.jsxs("div", { "aria-label": typeof label === "string" ? label : undefined, className: cvaTooltipPopoverContent({ color: mode }), "data-testid": dataTestId ? `${dataTestId}-content` : undefined, onClick: e => e.stopPropagation(), onDoubleClick: e => e.stopPropagation(), onMouseDown: e => e.stopPropagation(), onPointerDown: e => e.stopPropagation(), children: [jsxRuntime.jsx(Text, { "data-testid": dataTestId ? `${dataTestId}-text` : undefined, inverted: mode === "dark", size: "small", type: typeof label === "string" ? "p" : "span", children: label }), placement !== "auto" && jsxRuntime.jsx(FloatingArrowContainer, { arrowRef: arrowRef, mode: mode })] }) }) })) : null] }));
2291
+ return (jsxRuntime.jsxs(Popover, { activation: { click: false, hover: { delayed, interactable } }, className: cvaTooltipPopover(), "data-testid": dataTestId, id: id, onOpenStateChange: setIsOpen, placement: placement === "auto" ? "bottom" : placement, children: [jsxRuntime.jsx(PopoverTrigger, { ...rest, "data-testid": dataTestId ? `${dataTestId}-trigger` : null, ref: mergedRef, style: style, children: children === undefined ? (jsxRuntime.jsx(Icon, { className: cvaTooltipIcon({ color: mode }), "data-testid": dataTestId ? `${dataTestId}-icon` : undefined, name: "QuestionMarkCircle", size: "small", ...iconProps })) : (wrappedChildren) }), tooltipSuppressed || !isMounted ? null : (jsxRuntime.jsx("div", { ref: refs.setFloating, style: floatingStyles, children: jsxRuntime.jsx(PopoverContent, { initialFocus: -1, returnFocus: false, children: jsxRuntime.jsxs("div", { "aria-label": typeof label === "string" ? label : undefined, className: cvaTooltipPopoverContent({ color: mode }), "data-testid": dataTestId ? `${dataTestId}-content` : undefined, onClick: e => e.stopPropagation(), onDoubleClick: e => e.stopPropagation(), onMouseDown: e => e.stopPropagation(), onPointerDown: e => e.stopPropagation(), children: [jsxRuntime.jsx(Text, { "data-testid": dataTestId ? `${dataTestId}-text` : undefined, inverted: mode === "dark", size: "small", type: typeof label === "string" ? "p" : "span", children: label }), placement !== "auto" && jsxRuntime.jsx(FloatingArrowContainer, { arrowRef: arrowRef, mode: mode })] }) }) }))] }));
2279
2292
  };
2280
2293
 
2281
2294
  /**
package/index.esm.js CHANGED
@@ -2250,12 +2250,25 @@ const FloatingArrowContainer = ({ arrowRef, mode = "dark", }) => {
2250
2250
  * @param {TooltipProps} props - The props for the Tooltip component
2251
2251
  * @returns {ReactElement} Tooltip component
2252
2252
  */
2253
- const Tooltip = ({ children, "data-testid": dataTestId, disabled = false, label, placement = "auto", mode = "dark", iconProps, id, style, delayed = false, interactable = true, ref, ...rest }) => {
2253
+ const Tooltip = ({ children, "data-testid": dataTestId, disabled = false, label, placement = "auto", mode = "dark", iconProps, id, style, delayed = false, interactable = true, "data-state": dataState, ref, ...rest }) => {
2254
2254
  const [isOpen, setIsOpen] = useState(false);
2255
+ // PopoverTrigger marks the element that opened a menu or popover with data-state="open".
2256
+ // That state lands on this tooltip when it is the trigger, or on the child when a parent
2257
+ // such as IconButton forwards it. Keep the tooltip dismissed so it cannot sit on top of the popup.
2258
+ const triggerHasOpenPopup = dataState === "open" ||
2259
+ (isValidElement(children) && children.props["data-state"] === "open");
2260
+ const tooltipSuppressed = disabled || triggerHasOpenPopup;
2261
+ // Drop a hover-open in the same render that the trigger's popup opens. A later
2262
+ // effect would commit the tooltip once more and can restore it after the pointer
2263
+ // has already left. Disabled is left alone: a hover that starts while disabled
2264
+ // should still appear once the tooltip is enabled again.
2265
+ if (triggerHasOpenPopup && isOpen) {
2266
+ setIsOpen(false);
2267
+ }
2255
2268
  const arrowRef = useRef(null);
2256
2269
  const { refs, floatingStyles, context } = useFloating({
2257
2270
  placement: placement === "auto" ? "bottom" : placement,
2258
- open: disabled ? false : isOpen,
2271
+ open: tooltipSuppressed ? false : isOpen,
2259
2272
  onOpenChange: setIsOpen,
2260
2273
  middleware: [
2261
2274
  offset(8),
@@ -2274,7 +2287,7 @@ const Tooltip = ({ children, "data-testid": dataTestId, disabled = false, label,
2274
2287
  const wrappedChildren = useMemo(() => {
2275
2288
  return jsx(Slot, { children: children });
2276
2289
  }, [children]);
2277
- return (jsxs(Popover, { activation: { click: false, hover: { delayed, interactable } }, className: cvaTooltipPopover(), "data-testid": dataTestId, id: id, onOpenStateChange: setIsOpen, placement: placement === "auto" ? "bottom" : placement, children: [jsx(PopoverTrigger, { ...rest, "data-testid": dataTestId ? `${dataTestId}-trigger` : null, ref: mergedRef, style: style, children: children === undefined ? (jsx(Icon, { className: cvaTooltipIcon({ color: mode }), "data-testid": dataTestId ? `${dataTestId}-icon` : undefined, name: "QuestionMarkCircle", size: "small", ...iconProps })) : (wrappedChildren) }), isMounted ? (jsx("div", { ref: refs.setFloating, style: floatingStyles, children: jsx(PopoverContent, { initialFocus: -1, returnFocus: false, children: jsxs("div", { "aria-label": typeof label === "string" ? label : undefined, className: cvaTooltipPopoverContent({ color: mode }), "data-testid": dataTestId ? `${dataTestId}-content` : undefined, onClick: e => e.stopPropagation(), onDoubleClick: e => e.stopPropagation(), onMouseDown: e => e.stopPropagation(), onPointerDown: e => e.stopPropagation(), children: [jsx(Text, { "data-testid": dataTestId ? `${dataTestId}-text` : undefined, inverted: mode === "dark", size: "small", type: typeof label === "string" ? "p" : "span", children: label }), placement !== "auto" && jsx(FloatingArrowContainer, { arrowRef: arrowRef, mode: mode })] }) }) })) : null] }));
2290
+ return (jsxs(Popover, { activation: { click: false, hover: { delayed, interactable } }, className: cvaTooltipPopover(), "data-testid": dataTestId, id: id, onOpenStateChange: setIsOpen, placement: placement === "auto" ? "bottom" : placement, children: [jsx(PopoverTrigger, { ...rest, "data-testid": dataTestId ? `${dataTestId}-trigger` : null, ref: mergedRef, style: style, children: children === undefined ? (jsx(Icon, { className: cvaTooltipIcon({ color: mode }), "data-testid": dataTestId ? `${dataTestId}-icon` : undefined, name: "QuestionMarkCircle", size: "small", ...iconProps })) : (wrappedChildren) }), tooltipSuppressed || !isMounted ? null : (jsx("div", { ref: refs.setFloating, style: floatingStyles, children: jsx(PopoverContent, { initialFocus: -1, returnFocus: false, children: jsxs("div", { "aria-label": typeof label === "string" ? label : undefined, className: cvaTooltipPopoverContent({ color: mode }), "data-testid": dataTestId ? `${dataTestId}-content` : undefined, onClick: e => e.stopPropagation(), onDoubleClick: e => e.stopPropagation(), onMouseDown: e => e.stopPropagation(), onPointerDown: e => e.stopPropagation(), children: [jsx(Text, { "data-testid": dataTestId ? `${dataTestId}-text` : undefined, inverted: mode === "dark", size: "small", type: typeof label === "string" ? "p" : "span", children: label }), placement !== "auto" && jsx(FloatingArrowContainer, { arrowRef: arrowRef, mode: mode })] }) }) }))] }));
2278
2291
  };
2279
2292
 
2280
2293
  /**
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@trackunit/react-router-components",
3
- "version": "1.0.1",
3
+ "version": "1.0.5",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
7
7
  "node": ">=24.x"
8
8
  },
9
9
  "dependencies": {
10
- "@trackunit/css-class-variance-utilities": "2.6.7",
11
- "@trackunit/i18n-library-translation": "2.12.6",
12
- "@trackunit/react-components": "4.0.0",
13
- "@trackunit/react-drawer": "2.14.7",
14
- "@trackunit/shared-utils": "1.22.7",
10
+ "@trackunit/css-class-variance-utilities": "2.6.8",
11
+ "@trackunit/i18n-library-translation": "2.12.7",
12
+ "@trackunit/react-components": "4.0.3",
13
+ "@trackunit/react-drawer": "2.14.11",
14
+ "@trackunit/shared-utils": "1.22.8",
15
15
  "dequal": "^2.0.3",
16
16
  "zod": "^3.25.76"
17
17
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-components",
3
- "version": "4.0.0",
3
+ "version": "4.0.3",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "migrations": "./migrations.json",
@@ -14,15 +14,15 @@
14
14
  "@floating-ui/react": "^0.26.25",
15
15
  "string-ts": "^2.0.0",
16
16
  "tailwind-merge": "^3.7.0",
17
- "@trackunit/ui-design-tokens": "1.21.7",
18
- "@trackunit/css-class-variance-utilities": "2.6.7",
19
- "@trackunit/shared-utils": "1.22.7",
20
- "@trackunit/ui-icons": "1.20.7",
17
+ "@trackunit/ui-design-tokens": "1.21.8",
18
+ "@trackunit/css-class-variance-utilities": "2.6.8",
19
+ "@trackunit/shared-utils": "1.22.8",
20
+ "@trackunit/ui-icons": "1.20.8",
21
21
  "es-toolkit": "^1.52.0",
22
22
  "@tanstack/react-virtual": "^3.14.13",
23
23
  "fflate": "^0.8.3",
24
24
  "zod": "^3.25.76",
25
- "@trackunit/i18n-library-translation": "2.12.6"
25
+ "@trackunit/i18n-library-translation": "2.12.7"
26
26
  },
27
27
  "peerDependencies": {
28
28
  "react": "^19.0.0",
@@ -48,6 +48,11 @@ export interface TooltipProps extends Omit<CommonProps, "className">, Styleable,
48
48
  * @default true
49
49
  */
50
50
  interactable?: Pick<PopoverHoverOptions, "interactable">["interactable"];
51
+ /**
52
+ * Set by `PopoverTrigger` when this tooltip is the element that opens a menu or popover.
53
+ * While that popup is open the tooltip stays dismissed so the two overlays don't overlap.
54
+ */
55
+ "data-state"?: "open" | "closed";
51
56
  }
52
57
  /**
53
58
  * Tooltips display additional information upon hover. The information included should be contextual, helpful, and nonessential while providing that extra ability to communicate and give clarity to a user.
@@ -90,4 +95,4 @@ export interface TooltipProps extends Omit<CommonProps, "className">, Styleable,
90
95
  * @param {TooltipProps} props - The props for the Tooltip component
91
96
  * @returns {ReactElement} Tooltip component
92
97
  */
93
- export declare const Tooltip: ({ children, "data-testid": dataTestId, disabled, label, placement, mode, iconProps, id, style, delayed, interactable, ref, ...rest }: TooltipProps) => ReactElement;
98
+ export declare const Tooltip: ({ children, "data-testid": dataTestId, disabled, label, placement, mode, iconProps, id, style, delayed, interactable, "data-state": dataState, ref, ...rest }: TooltipProps) => ReactElement;