@@ -16,6 +16,7 @@ import {
1616 IconExclamationTriangleFill ,
1717 IconPlusSmall ,
1818 NumericInput ,
19+ PopperTooltip ,
1920 Prompt ,
2021 TextInput ,
2122 useNotificationApi ,
@@ -105,54 +106,85 @@ const NotificationChipList = ({
105106} : {
106107 notifications : QueuedNotification [ ] ;
107108 removeQueuedNotification : ( id : string ) => void ;
108- } ) => (
109- < div className = 'app__notification-dialog__chips' role = 'list' >
110- { notifications . map ( ( notification ) => {
111- const SeverityIcon = severityIcons [ notification . severity ] ;
112- const DirectionIcon = directionIcons [ notification . entryDirection ] ;
113-
114- return (
115- < div
116- className = 'app__notification-dialog__chip'
117- key = { notification . id }
118- role = 'listitem'
119- title = { notification . message }
120- >
121- { SeverityIcon && (
122- < SeverityIcon className = 'app__notification-dialog__chip-icon' />
123- ) }
124- < span className = 'app__notification-dialog__chip-text' >
125- { notification . message }
126- </ span >
127- < span className = 'app__notification-dialog__chip-meta' >
128- < span className = 'app__notification-dialog__chip-meta-item' >
129- < IconClock className = 'app__notification-dialog__chip-meta-icon' />
130- { formatDurationLabel ( notification . duration ) }
131- </ span >
132- < span className = 'app__notification-dialog__chip-meta-item' >
133- < DirectionIcon className = 'app__notification-dialog__chip-meta-icon' />
134- { notification . entryDirection }
109+ } ) => {
110+ const [ tooltipState , setTooltipState ] = useState < {
111+ referenceElement : HTMLDivElement ;
112+ text : string ;
113+ } | null > ( null ) ;
114+
115+ return (
116+ < div className = 'app__notification-dialog__chips' role = 'list' >
117+ { notifications . map ( ( notification ) => {
118+ const SeverityIcon = severityIcons [ notification . severity ] ;
119+ const DirectionIcon = directionIcons [ notification . entryDirection ] ;
120+
121+ return (
122+ < div
123+ className = 'app__notification-dialog__chip'
124+ key = { notification . id }
125+ onBlurCapture = { ( event ) => {
126+ if ( event . currentTarget . contains ( event . relatedTarget as Node | null ) ) {
127+ return ;
128+ }
129+ setTooltipState ( null ) ;
130+ } }
131+ onFocusCapture = { ( event ) =>
132+ setTooltipState ( {
133+ referenceElement : event . currentTarget ,
134+ text : notification . message ,
135+ } )
136+ }
137+ onMouseEnter = { ( event ) =>
138+ setTooltipState ( {
139+ referenceElement : event . currentTarget ,
140+ text : notification . message ,
141+ } )
142+ }
143+ onMouseLeave = { ( ) => setTooltipState ( null ) }
144+ role = 'listitem'
145+ >
146+ { SeverityIcon && (
147+ < SeverityIcon className = 'app__notification-dialog__chip-icon' />
148+ ) }
149+ < span className = 'app__notification-dialog__chip-text' >
150+ { notification . message }
135151 </ span >
136- < span className = 'app__notification-dialog__chip-panel' >
137- { notification . targetPanel }
152+ < span className = 'app__notification-dialog__chip-meta' >
153+ < span className = 'app__notification-dialog__chip-meta-item' >
154+ < IconClock className = 'app__notification-dialog__chip-meta-icon' />
155+ { formatDurationLabel ( notification . duration ) }
156+ </ span >
157+ < span className = 'app__notification-dialog__chip-meta-item' >
158+ < DirectionIcon className = 'app__notification-dialog__chip-meta-icon' />
159+ { notification . entryDirection }
160+ </ span >
161+ < span className = 'app__notification-dialog__chip-panel' >
162+ { notification . targetPanel }
163+ </ span >
138164 </ span >
139- </ span >
140- < Button
141- appearance = 'ghost'
142- aria-label = { `Remove ${ notification . message } ` }
143- circular
144- className = 'app__notification-dialog__chip-remove'
145- onClick = { ( ) => removeQueuedNotification ( notification . id ) }
146- size = 'xs'
147- variant = 'secondary'
148- >
149- < IconXmark />
150- </ Button >
151- </ div >
152- ) ;
153- } ) }
154- </ div >
155- ) ;
165+ < Button
166+ appearance = 'ghost'
167+ aria-label = { `Remove ${ notification . message } ` }
168+ circular
169+ className = 'app__notification-dialog__chip-remove'
170+ onClick = { ( ) => removeQueuedNotification ( notification . id ) }
171+ size = 'xs'
172+ variant = 'secondary'
173+ >
174+ < IconXmark />
175+ </ Button >
176+ </ div >
177+ ) ;
178+ } ) }
179+ < PopperTooltip
180+ referenceElement = { tooltipState ?. referenceElement ?? null }
181+ visible = { ! ! tooltipState }
182+ >
183+ { tooltipState ?. text ?? '' }
184+ </ PopperTooltip >
185+ </ div >
186+ ) ;
187+ } ;
156188
157189const NotificationDraftForm = ( {
158190 draft,
0 commit comments