1+ import { Tooltip } from "@components/ui/Tooltip" ;
12import { Button , cn } from "@posthog/quill" ;
3+ import { useCallback , useRef , useState } from "react" ;
24import type { SidebarItemAction } from "../types" ;
35
46const INDENT_SIZE = 8 ;
@@ -34,6 +36,34 @@ export function SidebarItem({
3436 endContent,
3537 disabled,
3638} : SidebarItemProps ) {
39+ const labelRef = useRef < HTMLSpanElement > ( null ) ;
40+ const [ showLabelTooltip , setShowLabelTooltip ] = useState ( false ) ;
41+ const canShowLabelTooltip =
42+ typeof label === "string" || typeof label === "number" ;
43+
44+ const handleLabelMouseEnter = useCallback ( ( ) => {
45+ const el = labelRef . current ;
46+ if ( el && el . scrollWidth > el . clientWidth ) {
47+ setShowLabelTooltip ( true ) ;
48+ }
49+ } , [ ] ) ;
50+
51+ const handleLabelMouseLeave = useCallback ( ( ) => {
52+ setShowLabelTooltip ( false ) ;
53+ } , [ ] ) ;
54+
55+ const labelSpan = (
56+ // biome-ignore lint/a11y/noStaticElementInteractions: hover handlers only drive a visual tooltip for truncated labels
57+ < span
58+ ref = { labelRef }
59+ className = "min-w-0 flex-1 overflow-hidden text-ellipsis whitespace-nowrap"
60+ onMouseEnter = { canShowLabelTooltip ? handleLabelMouseEnter : undefined }
61+ onMouseLeave = { canShowLabelTooltip ? handleLabelMouseLeave : undefined }
62+ >
63+ { label }
64+ </ span >
65+ ) ;
66+
3767 return (
3868 < Button
3969 type = "button"
@@ -59,9 +89,13 @@ export function SidebarItem({
5989 ) : null }
6090 < span className = "flex min-w-0 flex-1 flex-col overflow-hidden" >
6191 < span className = "flex h-[18px] items-center gap-1" >
62- < span className = "min-w-0 flex-1 overflow-hidden text-ellipsis whitespace-nowrap" >
63- { label }
64- </ span >
92+ { canShowLabelTooltip ? (
93+ < Tooltip content = { label } open = { showLabelTooltip } side = "top" >
94+ { labelSpan }
95+ </ Tooltip >
96+ ) : (
97+ labelSpan
98+ ) }
6599 { endContent }
66100 </ span >
67101 { subtitle && (
0 commit comments