@@ -112,6 +112,7 @@ export type Options = Partial< {
112112 offset : number ;
113113 autoFlip : boolean ;
114114 autoShift : boolean ;
115+ hideOnTargetClick : boolean ;
115116 delayToShow : number ;
116117 delayToHide : number ;
117118 additionalClass : string ;
@@ -133,6 +134,7 @@ interface HovercardRef {
133134 ref : HTMLElement ;
134135 onEnter : ( e : MouseEvent ) => void ;
135136 onLeave : ( e : MouseEvent ) => void ;
137+ onClick : ( e : MouseEvent ) => void ;
136138}
137139
138140const BASE_API_URL = 'https://api.gravatar.com/v3/profiles' ;
@@ -145,6 +147,7 @@ export default class Hovercards {
145147 _offset : number ;
146148 _autoFlip : boolean ;
147149 _autoShift : boolean ;
150+ _hideOnTargetClick : boolean ;
148151 _delayToShow : number ;
149152 _delayToHide : number ;
150153 _additionalClass : string ;
@@ -166,9 +169,10 @@ export default class Hovercards {
166169
167170 constructor ( {
168171 placement = 'right-start' ,
172+ offset = 10 ,
169173 autoFlip = true ,
170174 autoShift = true ,
171- offset = 10 ,
175+ hideOnTargetClick = false ,
172176 delayToShow = 500 ,
173177 delayToHide = 300 ,
174178 additionalClass = '' ,
@@ -183,9 +187,10 @@ export default class Hovercards {
183187 i18n = { } ,
184188 } : Options = { } ) {
185189 this . _placement = placement ;
190+ this . _offset = offset ;
186191 this . _autoFlip = autoFlip ;
187192 this . _autoShift = autoShift ;
188- this . _offset = offset ;
193+ this . _hideOnTargetClick = hideOnTargetClick ;
189194 this . _delayToShow = delayToShow ;
190195 this . _delayToHide = delayToHide ;
191196 this . _additionalClass = additionalClass ;
@@ -206,10 +211,10 @@ export default class Hovercards {
206211 * @param {HTMLElement } target - The element to query.
207212 * @param {string } dataAttributeName - Data attribute name associated with Gravatar hashes.
208213 * @param {string } [ignoreSelector] - The selector to ignore certain elements.
209- * @return {HTMLElement [] } - The queried hovercard refs.
214+ * @return {HovercardRef [] } - The queried hovercard refs.
210215 * @private
211216 */
212- _queryHovercardRefs ( target : HTMLElement , dataAttributeName : string , ignoreSelector ?: string ) {
217+ _queryHovercardRefs ( target : HTMLElement , dataAttributeName : string , ignoreSelector ?: string ) : HovercardRef [ ] {
213218 let refs : HTMLElement [ ] = [ ] ;
214219 const camelAttrName = dataAttributeName . replace ( / - ( [ a - z ] ) / g, ( g ) => g [ 1 ] . toUpperCase ( ) ) ;
215220 const ignoreRefs = ignoreSelector ? Array . from ( dc . querySelectorAll ( ignoreSelector ) ) : [ ] ;
@@ -291,6 +296,7 @@ export default class Hovercards {
291296 ...hovercardRef ,
292297 onEnter : ( e : MouseEvent ) => this . _handleMouseEnter ( e , hovercardRef ) ,
293298 onLeave : ( e : MouseEvent ) => this . _handleMouseLeave ( e , hovercardRef ) ,
299+ onClick : ( ) => this . _handleMouseClick ( hovercardRef ) ,
294300 } ) ) ;
295301
296302 return this . _hovercardRefs ;
@@ -306,7 +312,10 @@ export default class Hovercards {
306312 * @param {Object } [options.i18n] - The i18n object.
307313 * @return {HTMLDivElement } - The created hovercard element.
308314 */
309- static createHovercard : CreateHovercard = ( profileData , { additionalClass, myHash, i18n = { } } = { } ) => {
315+ static createHovercard : CreateHovercard = (
316+ profileData ,
317+ { additionalClass, myHash, i18n = { } } = { }
318+ ) : HTMLDivElement => {
310319 const {
311320 hash,
312321 avatarUrl,
@@ -658,7 +667,7 @@ export default class Hovercards {
658667 * @param {string } [options.additionalClass] - Additional CSS class for the skeleton hovercard.
659668 * @return {HTMLDivElement } - The created skeleton hovercard element.
660669 */
661- static createHovercardSkeleton : CreateHovercardSkeleton = ( { additionalClass } = { } ) => {
670+ static createHovercardSkeleton : CreateHovercardSkeleton = ( { additionalClass } = { } ) : HTMLDivElement => {
662671 const hovercard = dc . createElement ( 'div' ) ;
663672 hovercard . className = `gravatar-hovercard gravatar-hovercard--skeleton${
664673 additionalClass ? ` ${ additionalClass } ` : ''
@@ -699,7 +708,7 @@ export default class Hovercards {
699708 avatarUrl ,
700709 message ,
701710 { avatarAlt = 'Avatar' , additionalClass, additionalMessage = '' } = { }
702- ) => {
711+ ) : HTMLDivElement => {
703712 const hovercard = dc . createElement ( 'div' ) ;
704713 hovercard . className = `gravatar-hovercard gravatar-hovercard--error${
705714 additionalClass ? ` ${ additionalClass } ` : ''
@@ -726,7 +735,7 @@ export default class Hovercards {
726735 * @return {void }
727736 * @private
728737 */
729- _showHovercard ( { id, hash, params, ref } : HovercardRef ) {
738+ _showHovercard ( { id, hash, params, ref } : HovercardRef ) : void {
730739 const timeoutId = setTimeout ( ( ) => {
731740 if ( dc . getElementById ( id ) ) {
732741 return ;
@@ -878,32 +887,33 @@ export default class Hovercards {
878887 /**
879888 * Waits for a specified delay and hides the hovercard.
880889 *
881- * @param {string } id - The ID associated with the hovercard.
890+ * @param {string } id - The ID associated with the hovercard.
891+ * @param {number } [delay] - The delay in milliseconds before hiding the hovercard.
882892 * @return {void }
883893 * @private
884894 */
885- _hideHovercard ( id : string ) {
895+ _hideHovercard ( id : string , delay = this . _delayToHide ) : void {
886896 const timeoutId = setTimeout ( ( ) => {
887897 const hovercard = dc . getElementById ( id ) ;
888898
889899 if ( hovercard ) {
890900 hovercard . remove ( ) ;
891901 this . _onHovercardHidden ( id , hovercard as HTMLDivElement ) ;
892902 }
893- } , this . _delayToHide ) ;
903+ } , delay ) ;
894904
895905 this . _hideHovercardTimeoutIds . set ( id , timeoutId ) ;
896906 }
897907
898908 /**
899909 * Handles the mouseenter event for hovercard refs.
900910 *
901- * @param {MouseEvent } e - The mouseenter event object.
902- * @param hovercardRef - The hovercard ref object.
911+ * @param {MouseEvent } e - The mouseenter event object.
912+ * @param { HovercardRef } hovercardRef - The hovercard ref object.
903913 * @return {void }
904914 * @private
905915 */
906- _handleMouseEnter ( e : MouseEvent , hovercardRef : HovercardRef ) {
916+ _handleMouseEnter ( e : MouseEvent , hovercardRef : HovercardRef ) : void {
907917 if ( 'ontouchstart' in dc ) {
908918 return ;
909919 }
@@ -918,13 +928,13 @@ export default class Hovercards {
918928 /**
919929 * Handles the mouseleave event for hovercard refs.
920930 *
921- * @param {MouseEvent } e - The mouseleave event object.
922- * @param hovercardRef - The hovercard ref object.
923- * @param hovercardRef.id - The ID associated with the hovercard.
931+ * @param {MouseEvent } e - The mouseleave event object.
932+ * @param { HovercardRef } hovercardRef - The hovercard ref object.
933+ * @param { string } hovercardRef.id - The ID associated with the hovercard.
924934 * @return {void }
925935 * @private
926936 */
927- _handleMouseLeave ( e : MouseEvent , { id } : HovercardRef ) {
937+ _handleMouseLeave ( e : MouseEvent , { id } : HovercardRef ) : void {
928938 if ( 'ontouchstart' in dc ) {
929939 return ;
930940 }
@@ -935,16 +945,33 @@ export default class Hovercards {
935945 this . _hideHovercard ( id ) ;
936946 }
937947
948+ /**
949+ * Handles the click event for hovercard refs.
950+ *
951+ * @param {HovercardRef } hovercardRef - The hovercard ref object.
952+ * @param {string } hovercardRef.id - The ID associated with the hovercard.
953+ * @return {void }
954+ * @private
955+ */
956+ _handleMouseClick ( { id } : HovercardRef ) : void {
957+ if ( 'ontouchstart' in dc || ! this . _hideOnTargetClick ) {
958+ return ;
959+ }
960+
961+ clearInterval ( this . _showHovercardTimeoutIds . get ( id ) ) ;
962+ this . _hideHovercard ( id , 0 ) ;
963+ }
964+
938965 /**
939966 * Attaches event listeners on or within the target element.
940967 *
941968 * @param {HTMLElement } target - The target element to set.
942969 * @param {Object } [options={}] - The optional parameters.
943- * @param options.dataAttributeName - Data attribute name associated with Gravatar hashes.
944- * @param options.ignoreSelector - The selector to ignore certain elements.
970+ * @param { string } options.dataAttributeName - Data attribute name associated with Gravatar hashes.
971+ * @param { string } options.ignoreSelector - The selector to ignore certain elements.
945972 * @return {void }
946973 */
947- attach : Attach = ( target , { dataAttributeName = 'gravatar-hash' , ignoreSelector } = { } ) => {
974+ attach : Attach = ( target , { dataAttributeName = 'gravatar-hash' , ignoreSelector } = { } ) : void => {
948975 if ( ! target ) {
949976 return ;
950977 }
@@ -954,6 +981,7 @@ export default class Hovercards {
954981 this . _queryHovercardRefs ( target , dataAttributeName , ignoreSelector ) . forEach ( ( hovercardRef ) => {
955982 hovercardRef . ref . addEventListener ( 'mouseenter' , hovercardRef . onEnter ) ;
956983 hovercardRef . ref . addEventListener ( 'mouseleave' , hovercardRef . onLeave ) ;
984+ hovercardRef . ref . addEventListener ( 'click' , hovercardRef . onClick ) ;
957985 } ) ;
958986 } ;
959987
@@ -962,14 +990,19 @@ export default class Hovercards {
962990 *
963991 * @return {void }
964992 */
965- detach : Detach = ( ) => {
993+ detach : Detach = ( ) : void => {
966994 if ( ! this . _hovercardRefs . length ) {
967995 return ;
968996 }
969997
970998 this . _hovercardRefs . forEach ( ( hovercardRef ) => {
971999 hovercardRef . ref . removeEventListener ( 'mouseenter' , hovercardRef . onEnter ) ;
9721000 hovercardRef . ref . removeEventListener ( 'mouseleave' , hovercardRef . onLeave ) ;
1001+ hovercardRef . ref . removeEventListener ( 'click' , hovercardRef . onClick ) ;
1002+
1003+ // Clear the hovercard show timeout and remove the hovercard element.
1004+ clearInterval ( this . _showHovercardTimeoutIds . get ( hovercardRef . id ) ) ;
1005+ dc . getElementById ( hovercardRef . id ) ?. remove ( ) ;
9731006 } ) ;
9741007
9751008 this . _hovercardRefs = [ ] ;
0 commit comments