@@ -167,13 +167,15 @@ const proposedRectForSimpleTooltip =
167167
168168export type TooltipVariant = 'simple' | 'rich' ;
169169export type PaddingMode = 'small' | 'large' ;
170+ export type TooltipTrigger = 'hover' | 'click' | 'both' ;
170171
171172export interface TooltipProperties {
172173 id : string ;
173174 variant ?: TooltipVariant ;
174175 padding ?: PaddingMode ;
175176 anchor ?: HTMLElement ;
176177 jslogContext ?: string ;
178+ trigger ?: TooltipTrigger ;
177179}
178180
179181/**
@@ -182,25 +184,27 @@ export interface TooltipProperties {
182184 * @property hoverDelay - reflects the `"hover-delay"` attribute.
183185 * @property variant - reflects the `"variant"` attribute.
184186 * @property padding - reflects the `"padding"` attribute.
185- * @property useClick - reflects the `"click "` attribute.
187+ * @property trigger - reflects the `"trigger "` attribute.
186188 * @property verticalDistanceIncrease - reflects the `"vertical-distance-increase"` attribute.
187189 * @property preferSpanLeft - reflects the `"prefer-span-left"` attribute.
188190 * @attribute id - Id of the tooltip. Used for searching an anchor element with aria-describedby.
189191 * @attribute hover-delay - Hover length in ms before the tooltip is shown and hidden.
190192 * @attribute variant - Variant of the tooltip, `"simple"` for strings only, inverted background,
191193 * `"rich"` for interactive content, background according to theme's surface.
192194 * @attribute padding - Which padding to use, defaults to `"small"`. Use `"large"` for richer content.
193- * @attribute use-click - If present, the tooltip will be shown on click instead of on hover.
195+ * @attribute trigger - Specifies which action triggers the tooltip. `"hover"` is the default. `"click"` means the
196+ * tooltip will be shown on click instead of hover. `"both"` means both hover and click trigger the
197+ * tooltip.
194198 * @attribute vertical-distance-increase - The tooltip is moved vertically this many pixels further away from its anchor.
195199 * @attribute prefer-span-left - If present, the tooltip's preferred position is `"span-left"` (The right
196200 * side of the tooltip and its anchor are aligned. The tooltip expands to the left from
197201 * there.). Applies to rich tooltips only.
198202 * @attribute use-hotkey - If present, the tooltip will be shown on hover but not when receiving focus.
199- * Requires a hotkey to open when fosed (Alt-down). When `"use-click "` is present
200- * as well, use-click takes precedence.
203+ * Requires a hotkey to open when fosed (Alt-down). When `"trigger "` is present
204+ * as well, `"trigger"` takes precedence.
201205 */
202206export class Tooltip extends HTMLElement {
203- static readonly observedAttributes = [ 'id' , 'variant' , 'jslogcontext' ] ;
207+ static readonly observedAttributes = [ 'id' , 'variant' , 'jslogcontext' , 'trigger' ] ;
204208 static lastOpenedTooltipId : string | null = null ;
205209
206210 readonly #shadow = this . attachShadow ( { mode : 'open' } ) ;
@@ -231,16 +235,20 @@ export class Tooltip extends HTMLElement {
231235 }
232236 }
233237
234- get useClick ( ) : boolean {
235- return this . hasAttribute ( 'use-click' ) ?? false ;
236- }
237- set useClick ( useClick : boolean ) {
238- if ( useClick ) {
239- this . setAttribute ( 'use-click' , '' ) ;
240- } else {
241- this . removeAttribute ( 'use-click' ) ;
238+ get trigger ( ) : TooltipTrigger {
239+ switch ( this . getAttribute ( 'trigger' ) ) {
240+ case 'click' :
241+ return 'click' ;
242+ case 'both' :
243+ return 'both' ;
244+ case 'hover' :
245+ default :
246+ return 'hover' ;
242247 }
243248 }
249+ set trigger ( trigger : TooltipTrigger ) {
250+ this . setAttribute ( 'trigger' , trigger ) ;
251+ }
244252
245253 get hoverDelay ( ) : number {
246254 return this . hasAttribute ( 'hover-delay' ) ? Number ( this . getAttribute ( 'hover-delay' ) ) : 300 ;
@@ -297,7 +305,7 @@ export class Tooltip extends HTMLElement {
297305
298306 constructor ( properties ?: TooltipProperties ) {
299307 super ( ) ;
300- const { id, variant, padding, jslogContext, anchor} = properties ?? { } ;
308+ const { id, variant, padding, jslogContext, anchor, trigger } = properties ?? { } ;
301309 if ( id ) {
302310 this . id = id ;
303311 }
@@ -317,6 +325,9 @@ export class Tooltip extends HTMLElement {
317325 }
318326 this . #anchor = anchor ;
319327 }
328+ if ( trigger ) {
329+ this . trigger = trigger ;
330+ }
320331 }
321332
322333 attributeChangedCallback ( name : string , oldValue : string , newValue : string ) : void {
@@ -463,7 +474,7 @@ export class Tooltip extends HTMLElement {
463474 if ( ! this . hasAttribute ( 'role' ) ) {
464475 this . setAttribute ( 'role' , 'tooltip' ) ;
465476 }
466- this . setAttribute ( 'popover' , this . useClick ? 'auto ' : 'manual ' ) ;
477+ this . setAttribute ( 'popover' , this . trigger === 'hover' ? 'manual ' : 'auto ' ) ;
467478 this . #updateJslog( ) ;
468479 }
469480
@@ -474,6 +485,9 @@ export class Tooltip extends HTMLElement {
474485 #setClosing = ( event : Event ) : void => {
475486 if ( ( event as ToggleEvent ) . newState === 'closed' ) {
476487 this . #closing = true ;
488+ if ( this . #timeout) {
489+ window . clearTimeout ( this . #timeout) ;
490+ }
477491 }
478492 } ;
479493
@@ -521,9 +535,10 @@ export class Tooltip extends HTMLElement {
521535 // as we always want to support ESC to close.
522536 this . #anchor. addEventListener ( 'keydown' , this . #keyDown) ;
523537
524- if ( this . useClick ) {
538+ if ( this . trigger === 'click' || this . trigger === 'both' ) {
525539 this . #anchor. addEventListener ( 'click' , this . toggle ) ;
526- } else {
540+ }
541+ if ( this . trigger === 'hover' || this . trigger === 'both' ) {
527542 this . #anchor. addEventListener ( 'mouseenter' , this . showTooltip ) ;
528543 if ( ! this . useHotkey ) {
529544 this . #anchor. addEventListener ( 'focus' , this . showTooltip ) ;
0 commit comments