@@ -7,7 +7,10 @@ export type SafeHoverRect = Pick<
77
88export type SafeHoverSide = 'top' | 'bottom' | 'left' | 'right' ;
99
10- function isPointInPolygon ( point : SafeHoverPoint , polygon : SafeHoverPoint [ ] ) {
10+ export const isPointInPolygon = (
11+ point : SafeHoverPoint ,
12+ polygon : SafeHoverPoint [ ] ,
13+ ) => {
1114 const [ x , y ] = point ;
1215 let isInside = false ;
1316
@@ -23,63 +26,57 @@ function isPointInPolygon(point: SafeHoverPoint, polygon: SafeHoverPoint[]) {
2326 }
2427
2528 return isInside ;
26- }
29+ } ;
2730
28- function isPointInRect ( point : SafeHoverPoint , rect : SafeHoverRect ) {
31+ export const isPointInRect = ( point : SafeHoverPoint , rect : SafeHoverRect ) => {
2932 return (
3033 point [ 0 ] >= rect . left &&
3134 point [ 0 ] <= rect . right &&
3235 point [ 1 ] >= rect . top &&
3336 point [ 1 ] <= rect . bottom
3437 ) ;
35- }
38+ } ;
3639
37- export function getSafeHoverSide (
40+ export const getSafeHoverSide = (
3841 targetRect : SafeHoverRect ,
3942 popupRect : SafeHoverRect ,
40- ) : SafeHoverSide | null {
43+ ) : SafeHoverSide | null => {
4144 const gaps : { side : SafeHoverSide ; value : number } [ ] = [
4245 { side : 'top' , value : targetRect . top - popupRect . bottom } ,
4346 { side : 'bottom' , value : popupRect . top - targetRect . bottom } ,
4447 { side : 'left' , value : targetRect . left - popupRect . right } ,
4548 { side : 'right' , value : popupRect . left - targetRect . right } ,
4649 ] ;
47-
4850 const largestGap = gaps . reduce ( ( prev , next ) =>
4951 next . value > prev . value ? next : prev ,
5052 ) ;
51-
5253 return largestGap . value > 0 ? largestGap . side : null ;
53- }
54+ } ;
5455
55- function isLeavePointTowardsPopup (
56+ const isLeavePointTowardsPopup = (
5657 side : SafeHoverSide ,
5758 leavePoint : SafeHoverPoint ,
5859 targetRect : SafeHoverRect ,
59- ) {
60+ ) => {
6061 const [ x , y ] = leavePoint ;
61-
6262 switch ( side ) {
6363 case 'top' :
6464 return y <= targetRect . top + 1 ;
65-
6665 case 'bottom' :
6766 return y >= targetRect . bottom - 1 ;
68-
6967 case 'left' :
7068 return x <= targetRect . left + 1 ;
71-
7269 case 'right' :
7370 return x >= targetRect . right - 1 ;
7471 }
75- }
72+ } ;
7673
77- function getSafeHoverGapPolygon (
74+ const getSafeHoverGapPolygon = (
7875 side : SafeHoverSide ,
7976 targetRect : SafeHoverRect ,
8077 popupRect : SafeHoverRect ,
8178 buffer : number ,
82- ) : SafeHoverPoint [ ] {
79+ ) : SafeHoverPoint [ ] => {
8380 const verticalRect =
8481 popupRect . width > targetRect . width ? targetRect : popupRect ;
8582 const horizontalRect =
@@ -88,7 +85,6 @@ function getSafeHoverGapPolygon(
8885 const right = verticalRect . right + buffer ;
8986 const top = horizontalRect . top - buffer ;
9087 const bottom = horizontalRect . bottom + buffer ;
91-
9288 switch ( side ) {
9389 case 'top' :
9490 return [
@@ -97,23 +93,20 @@ function getSafeHoverGapPolygon(
9793 [ right , targetRect . top + 1 ] ,
9894 [ right , popupRect . bottom - 1 ] ,
9995 ] ;
100-
10196 case 'bottom' :
10297 return [
10398 [ left , targetRect . bottom - 1 ] ,
10499 [ left , popupRect . top + 1 ] ,
105100 [ right , popupRect . top + 1 ] ,
106101 [ right , targetRect . bottom - 1 ] ,
107102 ] ;
108-
109103 case 'left' :
110104 return [
111105 [ popupRect . right - 1 , top ] ,
112106 [ popupRect . right - 1 , bottom ] ,
113107 [ targetRect . left + 1 , bottom ] ,
114108 [ targetRect . left + 1 , top ] ,
115109 ] ;
116-
117110 case 'right' :
118111 return [
119112 [ targetRect . right - 1 , top ] ,
@@ -122,70 +115,66 @@ function getSafeHoverGapPolygon(
122115 [ popupRect . left + 1 , top ] ,
123116 ] ;
124117 }
125- }
118+ } ;
126119
127- function getSafeHoverIntentPolygon (
120+ const getSafeHoverIntentPolygon = (
128121 side : SafeHoverSide ,
129122 leavePoint : SafeHoverPoint ,
130123 popupRect : SafeHoverRect ,
131124 buffer : number ,
132- ) : SafeHoverPoint [ ] {
125+ ) : SafeHoverPoint [ ] => {
133126 switch ( side ) {
134127 case 'top' :
135128 return [
136129 leavePoint ,
137130 [ popupRect . left - buffer , popupRect . bottom + buffer ] ,
138131 [ popupRect . right + buffer , popupRect . bottom + buffer ] ,
139132 ] ;
140-
141133 case 'bottom' :
142134 return [
143135 leavePoint ,
144136 [ popupRect . right + buffer , popupRect . top - buffer ] ,
145137 [ popupRect . left - buffer , popupRect . top - buffer ] ,
146138 ] ;
147-
148139 case 'left' :
149140 return [
150141 leavePoint ,
151142 [ popupRect . right + buffer , popupRect . bottom + buffer ] ,
152143 [ popupRect . right + buffer , popupRect . top - buffer ] ,
153144 ] ;
154-
155145 case 'right' :
156146 return [
157147 leavePoint ,
158148 [ popupRect . left - buffer , popupRect . top - buffer ] ,
159149 [ popupRect . left - buffer , popupRect . bottom + buffer ] ,
160150 ] ;
161151 }
162- }
152+ } ;
163153
164- export function getSafeHoverAreaPolygons (
154+ export const getSafeHoverAreaPolygons = (
165155 leavePoint : SafeHoverPoint ,
166156 targetRect : SafeHoverRect ,
167157 popupRect : SafeHoverRect ,
168158 buffer = 0.5 ,
169- ) {
159+ ) => {
170160 const side = getSafeHoverSide ( targetRect , popupRect ) ;
171161
172162 if ( ! side || ! isLeavePointTowardsPopup ( side , leavePoint , targetRect ) ) {
173163 return [ ] ;
174164 }
175-
176165 return [
177166 getSafeHoverGapPolygon ( side , targetRect , popupRect , buffer ) ,
178167 getSafeHoverIntentPolygon ( side , leavePoint , popupRect , buffer ) ,
179168 ] ;
180- }
169+ } ;
181170
182- export function isPointInSafeHoverArea (
171+ export const isPointInSafeHoverArea = (
183172 point : SafeHoverPoint ,
184173 leavePoint : SafeHoverPoint ,
185174 targetRect : SafeHoverRect ,
186175 popupRect : SafeHoverRect ,
187176 buffer = 0.5 ,
188- ) {
177+ ) => {
189178 const safeHoverPolygons = getSafeHoverAreaPolygons (
190179 leavePoint ,
191180 targetRect ,
@@ -204,4 +193,4 @@ export function isPointInSafeHoverArea(
204193 // The gap polygon keeps the straight corridor open; the intent polygon
205194 // catches diagonal movement toward the popup edge.
206195 return safeHoverPolygons . some ( ( polygon ) => isPointInPolygon ( point , polygon ) ) ;
207- }
196+ } ;
0 commit comments