@trackunit/react-components 1.17.33-alpha-81fe60a7b8b.0 → 1.17.33

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
@@ -4226,8 +4226,13 @@ const usePopover = ({ initialOpen = false, placement = "bottom", isModal, isOpen
4226
4226
  keyboardHandlers: resolvedActivation.keyboardHandlers,
4227
4227
  });
4228
4228
  const dismissInteraction = react$1.useDismiss(popoverContext, resolvedDismissal);
4229
+ const hoverOptions = typeof resolvedActivation.hover === "object" ? resolvedActivation.hover : undefined;
4230
+ const hoverEnabled = hoverOptions ? (hoverOptions.active ?? true) : resolvedActivation.hover === true;
4231
+ const hoverInteractable = hoverOptions?.interactable ?? true;
4229
4232
  const hoverInteraction = react$1.useHover(popoverContext, {
4230
- enabled: resolvedActivation.hover,
4233
+ enabled: hoverEnabled,
4234
+ delay: hoverOptions?.delayed === true ? { open: 400 } : undefined,
4235
+ handleClose: hoverEnabled === true && hoverInteractable === true ? react$1.safePolygon() : undefined,
4231
4236
  });
4232
4237
  const roleInteraction = react$1.useRole(popoverContext);
4233
4238
  const combinedInteractions = react$1.useInteractions([
@@ -4507,7 +4512,7 @@ const cvaTooltipIcon = cssClassVarianceUtilities.cvaMerge(["text-neutral-300", "
4507
4512
  },
4508
4513
  },
4509
4514
  });
4510
- const cvaTooltipPopover = cssClassVarianceUtilities.cvaMerge(["pointer-events-none", "origin-center"]);
4515
+ const cvaTooltipPopover = cssClassVarianceUtilities.cvaMerge(["origin-center"]);
4511
4516
  const cvaTooltipPopoverTail = cssClassVarianceUtilities.cvaMerge("", {
4512
4517
  variants: {
4513
4518
  placement: {
@@ -4596,7 +4601,7 @@ const FloatingArrowContainer = ({ arrowRef, mode = "dark", }) => {
4596
4601
  * @param {TooltipProps} props - The props for the Tooltip component
4597
4602
  * @returns {ReactElement} Tooltip component
4598
4603
  */
4599
- const Tooltip = ({ children, "data-testid": dataTestId, disabled = false, label, placement = "auto", mode = "dark", iconProps, id, style, }) => {
4604
+ const Tooltip = ({ children, "data-testid": dataTestId, disabled = false, label, placement = "auto", mode = "dark", iconProps, id, style, delayed = false, interactable = true, }) => {
4600
4605
  const [isOpen, setIsOpen] = react.useState(false);
4601
4606
  const arrowRef = react.useRef(null);
4602
4607
  const { refs, floatingStyles, context } = react$1.useFloating({
@@ -4614,12 +4619,12 @@ const Tooltip = ({ children, "data-testid": dataTestId, disabled = false, label,
4614
4619
  whileElementsMounted: react$1.autoUpdate,
4615
4620
  });
4616
4621
  const { isMounted } = react$1.useTransitionStatus(context);
4617
- // Please don't try to move this into the component body directly
4618
- // I tried and it caused infinite re-renders some places (for whatever reason)
4622
+ // Please don't move this into the component body directly without testing it first
4623
+ // I tried and it caused infinite re-renders some places
4619
4624
  const wrappedChildren = react.useMemo(() => {
4620
4625
  return jsxRuntime.jsx(reactSlot.Slot, { children: children });
4621
4626
  }, [children]);
4622
- return (jsxRuntime.jsxs(Popover, { activation: { hover: true }, className: cvaTooltipPopover(), "data-testid": dataTestId, id: id, onOpenStateChange: setIsOpen, placement: placement === "auto" ? "bottom" : placement, children: [jsxRuntime.jsx(PopoverTrigger, { "data-testid": dataTestId ? `${dataTestId}-trigger` : null, ref: refs.setReference, 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, { children: jsxRuntime.jsxs("div", { "aria-label": typeof label === "string" ? label : undefined, className: cvaTooltipPopoverContent({ color: mode }), "data-testid": dataTestId ? `${dataTestId}-content` : undefined, 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] }));
4627
+ return (jsxRuntime.jsxs(Popover, { activation: { hover: { delayed, interactable } }, className: cvaTooltipPopover(), "data-testid": dataTestId, id: id, onOpenStateChange: setIsOpen, placement: placement === "auto" ? "bottom" : placement, children: [jsxRuntime.jsx(PopoverTrigger, { "data-testid": dataTestId ? `${dataTestId}-trigger` : null, ref: refs.setReference, 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, { children: jsxRuntime.jsxs("div", { "aria-label": typeof label === "string" ? label : undefined, className: cvaTooltipPopoverContent({ color: mode }), "data-testid": dataTestId ? `${dataTestId}-content` : undefined, 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] }));
4623
4628
  };
4624
4629
 
4625
4630
  const cvaIndicator = cssClassVarianceUtilities.cvaMerge(["inline-flex", "items-center"]);
package/index.esm.js CHANGED
@@ -13,7 +13,7 @@ import { Slot, Slottable } from '@radix-ui/react-slot';
13
13
  import { Link, useBlocker } from '@tanstack/react-router';
14
14
  import { isEqual, omit } from 'es-toolkit';
15
15
  import { twMerge } from 'tailwind-merge';
16
- import { useFloating, offset, flip, shift, size, autoUpdate, useClick, useDismiss, useHover as useHover$1, useRole, useInteractions, FloatingPortal, useMergeRefs as useMergeRefs$1, FloatingFocusManager, arrow, useTransitionStatus, FloatingArrow } from '@floating-ui/react';
16
+ import { useFloating, offset, flip, shift, size, autoUpdate, useClick, useDismiss, useHover as useHover$1, safePolygon, useRole, useInteractions, FloatingPortal, useMergeRefs as useMergeRefs$1, FloatingFocusManager, arrow, useTransitionStatus, FloatingArrow } from '@floating-ui/react';
17
17
  import { useVirtualizer } from '@tanstack/react-virtual';
18
18
  import { HelmetProvider, Helmet } from 'react-helmet-async';
19
19
  import { Trigger, Content, List as List$1, Root } from '@radix-ui/react-tabs';
@@ -4224,8 +4224,13 @@ const usePopover = ({ initialOpen = false, placement = "bottom", isModal, isOpen
4224
4224
  keyboardHandlers: resolvedActivation.keyboardHandlers,
4225
4225
  });
4226
4226
  const dismissInteraction = useDismiss(popoverContext, resolvedDismissal);
4227
+ const hoverOptions = typeof resolvedActivation.hover === "object" ? resolvedActivation.hover : undefined;
4228
+ const hoverEnabled = hoverOptions ? (hoverOptions.active ?? true) : resolvedActivation.hover === true;
4229
+ const hoverInteractable = hoverOptions?.interactable ?? true;
4227
4230
  const hoverInteraction = useHover$1(popoverContext, {
4228
- enabled: resolvedActivation.hover,
4231
+ enabled: hoverEnabled,
4232
+ delay: hoverOptions?.delayed === true ? { open: 400 } : undefined,
4233
+ handleClose: hoverEnabled === true && hoverInteractable === true ? safePolygon() : undefined,
4229
4234
  });
4230
4235
  const roleInteraction = useRole(popoverContext);
4231
4236
  const combinedInteractions = useInteractions([
@@ -4505,7 +4510,7 @@ const cvaTooltipIcon = cvaMerge(["text-neutral-300", "transition", "hover:cursor
4505
4510
  },
4506
4511
  },
4507
4512
  });
4508
- const cvaTooltipPopover = cvaMerge(["pointer-events-none", "origin-center"]);
4513
+ const cvaTooltipPopover = cvaMerge(["origin-center"]);
4509
4514
  const cvaTooltipPopoverTail = cvaMerge("", {
4510
4515
  variants: {
4511
4516
  placement: {
@@ -4594,7 +4599,7 @@ const FloatingArrowContainer = ({ arrowRef, mode = "dark", }) => {
4594
4599
  * @param {TooltipProps} props - The props for the Tooltip component
4595
4600
  * @returns {ReactElement} Tooltip component
4596
4601
  */
4597
- const Tooltip = ({ children, "data-testid": dataTestId, disabled = false, label, placement = "auto", mode = "dark", iconProps, id, style, }) => {
4602
+ const Tooltip = ({ children, "data-testid": dataTestId, disabled = false, label, placement = "auto", mode = "dark", iconProps, id, style, delayed = false, interactable = true, }) => {
4598
4603
  const [isOpen, setIsOpen] = useState(false);
4599
4604
  const arrowRef = useRef(null);
4600
4605
  const { refs, floatingStyles, context } = useFloating({
@@ -4612,12 +4617,12 @@ const Tooltip = ({ children, "data-testid": dataTestId, disabled = false, label,
4612
4617
  whileElementsMounted: autoUpdate,
4613
4618
  });
4614
4619
  const { isMounted } = useTransitionStatus(context);
4615
- // Please don't try to move this into the component body directly
4616
- // I tried and it caused infinite re-renders some places (for whatever reason)
4620
+ // Please don't move this into the component body directly without testing it first
4621
+ // I tried and it caused infinite re-renders some places
4617
4622
  const wrappedChildren = useMemo(() => {
4618
4623
  return jsx(Slot, { children: children });
4619
4624
  }, [children]);
4620
- return (jsxs(Popover, { activation: { hover: true }, className: cvaTooltipPopover(), "data-testid": dataTestId, id: id, onOpenStateChange: setIsOpen, placement: placement === "auto" ? "bottom" : placement, children: [jsx(PopoverTrigger, { "data-testid": dataTestId ? `${dataTestId}-trigger` : null, ref: refs.setReference, 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, { children: jsxs("div", { "aria-label": typeof label === "string" ? label : undefined, className: cvaTooltipPopoverContent({ color: mode }), "data-testid": dataTestId ? `${dataTestId}-content` : undefined, 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] }));
4625
+ return (jsxs(Popover, { activation: { hover: { delayed, interactable } }, className: cvaTooltipPopover(), "data-testid": dataTestId, id: id, onOpenStateChange: setIsOpen, placement: placement === "auto" ? "bottom" : placement, children: [jsx(PopoverTrigger, { "data-testid": dataTestId ? `${dataTestId}-trigger` : null, ref: refs.setReference, 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, { children: jsxs("div", { "aria-label": typeof label === "string" ? label : undefined, className: cvaTooltipPopoverContent({ color: mode }), "data-testid": dataTestId ? `${dataTestId}-content` : undefined, 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] }));
4621
4626
  };
4622
4627
 
4623
4628
  const cvaIndicator = cvaMerge(["inline-flex", "items-center"]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-components",
3
- "version": "1.17.33-alpha-81fe60a7b8b.0",
3
+ "version": "1.17.33",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -14,10 +14,10 @@
14
14
  "@floating-ui/react": "^0.26.25",
15
15
  "string-ts": "^2.0.0",
16
16
  "tailwind-merge": "^2.0.0",
17
- "@trackunit/ui-design-tokens": "1.11.49-alpha-81fe60a7b8b.0",
18
- "@trackunit/css-class-variance-utilities": "1.11.49-alpha-81fe60a7b8b.0",
19
- "@trackunit/shared-utils": "1.13.49-alpha-81fe60a7b8b.0",
20
- "@trackunit/ui-icons": "1.11.48-alpha-81fe60a7b8b.0",
17
+ "@trackunit/ui-design-tokens": "1.11.48",
18
+ "@trackunit/css-class-variance-utilities": "1.11.48",
19
+ "@trackunit/shared-utils": "1.13.48",
20
+ "@trackunit/ui-icons": "1.11.47",
21
21
  "@tanstack/react-router": "1.114.29",
22
22
  "es-toolkit": "^1.39.10",
23
23
  "@tanstack/react-virtual": "3.13.12",
@@ -1,9 +1,30 @@
1
1
  import { ExtendedRefs, ReferenceType, UseDismissProps, UseFloatingReturn } from "@floating-ui/react";
2
2
  import { Dispatch, HTMLProps, SetStateAction } from "react";
3
3
  import { CommonProps } from "../../common/CommonProps";
4
+ export type PopoverHoverOptions = {
5
+ /**
6
+ * Whether hover activation is enabled.
7
+ *
8
+ * @default true
9
+ */
10
+ active?: boolean;
11
+ /**
12
+ * Whether to add a 400ms delay before the floating element opens on hover.
13
+ *
14
+ * @default false
15
+ */
16
+ delayed?: boolean;
17
+ /**
18
+ * Whether the cursor can reach and interact with the floating element.
19
+ * Enables safePolygon so the element stays open while the cursor moves toward it.
20
+ *
21
+ * @default true
22
+ */
23
+ interactable?: boolean;
24
+ };
4
25
  export type PopoverActivation = {
5
26
  click?: boolean;
6
- hover?: boolean;
27
+ hover?: boolean | PopoverHoverOptions;
7
28
  keyboardHandlers?: boolean;
8
29
  };
9
30
  export type PopoverDismissal = Pick<UseDismissProps, "ancestorScroll" | "enabled" | "outsidePress">;
@@ -3,6 +3,7 @@ import { ReactElement, ReactNode } from "react";
3
3
  import { CommonProps } from "../../common/CommonProps";
4
4
  import { Styleable } from "../../common/Styleable";
5
5
  import { IconProps } from "../Icon/Icon";
6
+ import { PopoverHoverOptions } from "../Popover/PopoverTypes";
6
7
  export type TooltipPlacement = Placement | "auto";
7
8
  export interface TooltipProps extends Omit<CommonProps, "className">, Styleable {
8
9
  /**
@@ -33,6 +34,19 @@ export interface TooltipProps extends Omit<CommonProps, "className">, Styleable
33
34
  * Ihe id of the html element
34
35
  */
35
36
  id?: string;
37
+ /**
38
+ * Whether to add a 400ms delay before the tooltip opens on hover.
39
+ *
40
+ * @default false
41
+ */
42
+ delayed?: Pick<PopoverHoverOptions, "delayed">["delayed"];
43
+ /**
44
+ * Whether the cursor can reach and interact with the tooltip content.
45
+ * Enables safePolygon so the tooltip stays open while the cursor moves toward it.
46
+ *
47
+ * @default true
48
+ */
49
+ interactable?: Pick<PopoverHoverOptions, "interactable">["interactable"];
36
50
  }
37
51
  /**
38
52
  * 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.
@@ -75,4 +89,4 @@ export interface TooltipProps extends Omit<CommonProps, "className">, Styleable
75
89
  * @param {TooltipProps} props - The props for the Tooltip component
76
90
  * @returns {ReactElement} Tooltip component
77
91
  */
78
- export declare const Tooltip: ({ children, "data-testid": dataTestId, disabled, label, placement, mode, iconProps, id, style, }: TooltipProps) => ReactElement;
92
+ export declare const Tooltip: ({ children, "data-testid": dataTestId, disabled, label, placement, mode, iconProps, id, style, delayed, interactable, }: TooltipProps) => ReactElement;