@@ -2,19 +2,22 @@ import { Tooltip as KobalteTooltip } from "@kobalte/core/tooltip"
22import { createEffect , Match , onCleanup , splitProps , Switch , type JSX } from "solid-js"
33import type { ComponentProps } from "solid-js"
44import { createStore } from "solid-js/store"
5+ import { closeTooltipIntent , openTooltipIntent , resetTooltipIntent } from "./tooltip-intent"
56import "./tooltip-v2.css"
67
7- export interface TooltipV2Props extends ComponentProps < typeof KobalteTooltip > {
8+ export interface TooltipV2Props extends Omit < ComponentProps < typeof KobalteTooltip > , "openDelay" > {
89 value : JSX . Element
910 class ?: string
1011 contentClass ?: string
1112 contentStyle ?: JSX . CSSProperties
1213 inactive ?: boolean
14+ delay ?: "standard" | "intent"
1315 forceOpen ?: boolean
1416}
1517
1618export function TooltipV2 ( props : TooltipV2Props ) {
1719 let ref : HTMLDivElement | undefined
20+ let cancelIntent : ( ( ) => void ) | undefined
1821 const [ state , setState ] = createStore ( {
1922 open : false ,
2023 block : false ,
@@ -26,19 +29,37 @@ export function TooltipV2(props: TooltipV2Props) {
2629 "contentClass" ,
2730 "contentStyle" ,
2831 "inactive" ,
32+ "delay" ,
2933 "forceOpen" ,
3034 "ignoreSafeArea" ,
3135 "value" ,
3236 ] )
3337
34- const close = ( ) => setState ( "open" , false )
35-
3638 const inside = ( ) => {
3739 const active = document . activeElement
3840 if ( ! ref || ! active ) return false
3941 return ref . contains ( active )
4042 }
4143
44+ const close = ( ) => {
45+ cancelIntent ?.( )
46+ cancelIntent = undefined
47+ if ( local . delay === "intent" ) closeTooltipIntent ( )
48+ setState ( "open" , false )
49+ }
50+
51+ const show = ( ) => {
52+ if ( local . delay !== "intent" || inside ( ) ) {
53+ setState ( "open" , true )
54+ return
55+ }
56+ if ( cancelIntent ) return
57+ cancelIntent = openTooltipIntent ( ( ) => {
58+ cancelIntent = undefined
59+ setState ( "open" , true )
60+ } )
61+ }
62+
4263 const drop = ( expand = state . expand ) => {
4364 if ( expand ) return
4465 if ( ref ?. matches ( ":hover" ) ) return
@@ -80,6 +101,11 @@ export function TooltipV2(props: TooltipV2Props) {
80101 onCleanup ( ( ) => obs . disconnect ( ) )
81102 } )
82103
104+ onCleanup ( ( ) => {
105+ cancelIntent ?.( )
106+ if ( local . delay === "intent" ) resetTooltipIntent ( )
107+ } )
108+
83109 let justClickedTrigger = false
84110
85111 return (
@@ -88,8 +114,8 @@ export function TooltipV2(props: TooltipV2Props) {
88114 < Match when = { true } >
89115 < KobalteTooltip
90116 gutter = { 4 }
91- openDelay = { 400 }
92- skipDelayDuration = { 300 }
117+ openDelay = { local . delay === "intent" ? 0 : 400 }
118+ skipDelayDuration = { local . delay === "intent" ? 0 : 300 }
93119 { ...others }
94120 closeDelay = { 0 }
95121 ignoreSafeArea = { local . ignoreSafeArea ?? true }
@@ -101,7 +127,11 @@ export function TooltipV2(props: TooltipV2Props) {
101127 justClickedTrigger = false
102128 return
103129 }
104- setState ( "open" , open )
130+ if ( open ) {
131+ show ( )
132+ return
133+ }
134+ close ( )
105135 } }
106136 >
107137 < KobalteTooltip . Trigger
0 commit comments