11import { Tooltip as KobalteTooltip } from "@kobalte/core/tooltip"
2- import { createEffect , Match , onCleanup , splitProps , Switch , type JSX } from "solid-js"
2+ import { makeEventListener } from "@solid-primitives/event-listener"
3+ import { createEffect , createRenderEffect , Match , onCleanup , splitProps , Switch , type JSX } from "solid-js"
34import type { ComponentProps } from "solid-js"
45import { createStore } from "solid-js/store"
56import "./tooltip-v2.css"
@@ -11,6 +12,7 @@ export interface TooltipV2Props extends ComponentProps<typeof KobalteTooltip> {
1112 contentStyle ?: JSX . CSSProperties
1213 inactive ?: boolean
1314 forceOpen ?: boolean
15+ keepOpenOnScroll ?: boolean
1416}
1517
1618export function TooltipV2 ( props : TooltipV2Props ) {
@@ -27,6 +29,7 @@ export function TooltipV2(props: TooltipV2Props) {
2729 "contentStyle" ,
2830 "inactive" ,
2931 "forceOpen" ,
32+ "keepOpenOnScroll" ,
3033 "ignoreSafeArea" ,
3134 "value" ,
3235 ] )
@@ -62,7 +65,35 @@ export function TooltipV2(props: TooltipV2Props) {
6265 close ( )
6366 }
6467
68+ let scrollingTrigger = false
69+ let scrollFrame : number | undefined
70+
71+ const clearScroll = ( ) => {
72+ if ( scrollFrame !== undefined ) cancelAnimationFrame ( scrollFrame )
73+ scrollFrame = undefined
74+ scrollingTrigger = false
75+ }
76+
77+ createRenderEffect ( ( ) => {
78+ if ( ! local . keepOpenOnScroll ) return
79+ makeEventListener (
80+ window ,
81+ "scroll" ,
82+ ( event ) => {
83+ if ( ! state . open || ! ref || ! ( event . target instanceof Node ) || ! event . target . contains ( ref ) ) return
84+ clearScroll ( )
85+ scrollingTrigger = true
86+ scrollFrame = requestAnimationFrame ( ( ) => {
87+ scrollingTrigger = false
88+ scrollFrame = undefined
89+ } )
90+ } ,
91+ { capture : true } ,
92+ )
93+ } )
94+
6595 const leave = ( ) => {
96+ clearScroll ( )
6697 if ( ! inside ( ) ) close ( )
6798 drop ( )
6899 }
@@ -97,6 +128,7 @@ export function TooltipV2(props: TooltipV2Props) {
97128 onOpenChange = { ( open ) => {
98129 if ( local . forceOpen ) return
99130 if ( state . block && open ) return
131+ if ( ! open && scrollingTrigger && ref ?. matches ( ":hover" ) ) return
100132 if ( justClickedTrigger ) {
101133 justClickedTrigger = false
102134 return
@@ -110,6 +142,7 @@ export function TooltipV2(props: TooltipV2Props) {
110142 data-component = "tooltip-v2-trigger"
111143 class = { local . class }
112144 onPointerDownCapture = { arm }
145+ onBlur = { clearScroll }
113146 onKeyDownCapture = { ( event : KeyboardEvent ) => {
114147 if ( event . key !== "Enter" && event . key !== " " ) return
115148 arm ( )
@@ -130,6 +163,7 @@ export function TooltipV2(props: TooltipV2Props) {
130163 data-force-open = { local . forceOpen }
131164 class = { local . contentClass }
132165 style = { local . contentStyle }
166+ onEscapeKeyDown = { clearScroll }
133167 onPointerDownOutside = { ( e ) => {
134168 if ( ref === e . target || ( e . target instanceof Node && ref ?. contains ( e . target ) ) ) {
135169 justClickedTrigger = true
0 commit comments