@@ -74,10 +74,15 @@ const TruncateBase: React.FunctionComponent<TruncateProps> = ({
7474 omissionContent = '\u2026' ,
7575 content,
7676 innerRef,
77+ onMouseEnter,
78+ onMouseLeave,
79+ onFocus,
80+ onBlur,
7781 ...props
7882} : TruncateProps ) => {
7983 const [ isTruncated , setIsTruncated ] = useState ( true ) ;
8084 const [ shouldRenderByMaxChars , setShouldRenderByMaxChars ] = useState ( maxCharsDisplayed > 0 ) ;
85+ const [ showTooltip , setShowTooltip ] = useState ( false ) ;
8186
8287 const textRef = useRef < HTMLElement > ( null ) ;
8388 useImperativeHandle ( innerRef , ( ) => textRef . current ! ) ;
@@ -93,12 +98,49 @@ const TruncateBase: React.FunctionComponent<TruncateProps> = ({
9398 if ( shouldRenderByMaxChars ) {
9499 setIsTruncated ( content . length > maxCharsDisplayed ) ;
95100 }
96- } , [ shouldRenderByMaxChars ] ) ;
101+ } , [ shouldRenderByMaxChars , content . length , maxCharsDisplayed ] ) ;
97102
98103 useEffect ( ( ) => {
99104 setShouldRenderByMaxChars ( maxCharsDisplayed > 0 ) ;
100105 } , [ maxCharsDisplayed ] ) ;
101106
107+ // Check if content is truncated (called on hover/focus)
108+ const checkTruncation = ( ) : boolean => {
109+ if ( shouldRenderByMaxChars ) {
110+ return isTruncated ;
111+ }
112+
113+ if ( ! textRef . current ) {
114+ return false ;
115+ }
116+
117+ return textRef . current . scrollWidth > textRef . current . clientWidth ;
118+ } ;
119+
120+ const handleMouseEnter = ( e : React . MouseEvent < HTMLElement > ) => {
121+ if ( checkTruncation ( ) ) {
122+ setShowTooltip ( true ) ;
123+ }
124+ onMouseEnter ?.( e ) ;
125+ } ;
126+
127+ const handleMouseLeave = ( e : React . MouseEvent < HTMLElement > ) => {
128+ setShowTooltip ( false ) ;
129+ onMouseLeave ?.( e ) ;
130+ } ;
131+
132+ const handleFocus = ( e : React . FocusEvent < HTMLElement > ) => {
133+ if ( checkTruncation ( ) ) {
134+ setShowTooltip ( true ) ;
135+ }
136+ onFocus ?.( e ) ;
137+ } ;
138+
139+ const handleBlur = ( e : React . FocusEvent < HTMLElement > ) => {
140+ setShowTooltip ( false ) ;
141+ onBlur ?.( e ) ;
142+ } ;
143+
102144 const lrmEntity = < Fragment > ‎</ Fragment > ;
103145 const isStartPosition = position === TruncatePosition . start ;
104146 const isEndPosition = position === TruncatePosition . end ;
@@ -186,6 +228,10 @@ const TruncateBase: React.FunctionComponent<TruncateProps> = ({
186228 href = { href }
187229 className = { css ( styles . truncate , shouldRenderByMaxChars && styles . modifiers . fixed , className ) }
188230 { ...( isTruncated && ! href && ! tooltipProps ?. triggerRef && { tabIndex : 0 } ) }
231+ onMouseEnter = { handleMouseEnter }
232+ onMouseLeave = { handleMouseLeave }
233+ onFocus = { handleFocus }
234+ onBlur = { handleBlur }
189235 { ...props }
190236 >
191237 { ! shouldRenderByMaxChars ? renderResizeObserverContent ( ) : renderMaxDisplayContent ( ) }
@@ -194,15 +240,14 @@ const TruncateBase: React.FunctionComponent<TruncateProps> = ({
194240
195241 return (
196242 < >
197- { isTruncated && (
198- < Tooltip
199- hidden = { ! isTruncated }
200- position = { tooltipPosition }
201- content = { content }
202- triggerRef = { subParentRef }
203- { ...tooltipProps }
204- />
205- ) }
243+ < Tooltip
244+ position = { tooltipPosition }
245+ content = { content }
246+ triggerRef = { subParentRef }
247+ trigger = "manual"
248+ isVisible = { showTooltip }
249+ { ...tooltipProps }
250+ />
206251 { truncateBody }
207252 </ >
208253 ) ;
0 commit comments