1- import { Placement , Offset } from "@/hooks/usePopover" ;
1+ import { Placement , Offset , Alignment } from "@/hooks/usePopover" ;
22
33export interface Position {
44 top : number ;
@@ -9,45 +9,75 @@ interface PositionConfig {
99 triggerRect : DOMRect ;
1010 contentRect : DOMRect ;
1111 offset : Offset ;
12+ align : Alignment ;
1213}
1314
15+ const alignmentMap : Record <
16+ Alignment ,
17+ ( triggerSize : number , contentSize : number ) => number
18+ > = {
19+ start : ( ) => 0 ,
20+ center : ( triggerSize , contentSize ) => ( triggerSize - contentSize ) / 2 ,
21+ end : ( triggerSize , contentSize ) => triggerSize - contentSize ,
22+ } ;
23+
24+ const getAlignment = (
25+ triggerSize : number ,
26+ contentSize : number ,
27+ align : Alignment ,
28+ ) : number => {
29+ return alignmentMap [ align ] ( triggerSize , contentSize ) ;
30+ } ;
31+
1432const getTopPosition = ( {
1533 triggerRect,
1634 contentRect,
1735 offset,
36+ align,
1837} : PositionConfig ) : Position => ( {
1938 top : triggerRect . top - contentRect . height - offset . y ,
2039 left :
21- triggerRect . left + ( triggerRect . width - contentRect . width ) / 2 + offset . x ,
40+ triggerRect . left +
41+ getAlignment ( triggerRect . width , contentRect . width , align ) +
42+ offset . x ,
2243} ) ;
2344
2445const getRightPosition = ( {
2546 triggerRect,
2647 contentRect,
2748 offset,
49+ align,
2850} : PositionConfig ) : Position => ( {
2951 top :
30- triggerRect . top + ( triggerRect . height - contentRect . height ) / 2 + offset . y ,
52+ triggerRect . top +
53+ getAlignment ( triggerRect . height , contentRect . height , align ) +
54+ offset . y ,
3155 left : triggerRect . right + offset . x ,
3256} ) ;
3357
3458const getBottomPosition = ( {
3559 triggerRect,
3660 contentRect,
3761 offset,
62+ align,
3863} : PositionConfig ) : Position => ( {
3964 top : triggerRect . bottom + offset . y ,
4065 left :
41- triggerRect . left + ( triggerRect . width - contentRect . width ) / 2 + offset . x ,
66+ triggerRect . left +
67+ getAlignment ( triggerRect . width , contentRect . width , align ) +
68+ offset . x ,
4269} ) ;
4370
4471const getLeftPosition = ( {
4572 triggerRect,
4673 contentRect,
4774 offset,
75+ align,
4876} : PositionConfig ) : Position => ( {
4977 top :
50- triggerRect . top + ( triggerRect . height - contentRect . height ) / 2 + offset . y ,
78+ triggerRect . top +
79+ getAlignment ( triggerRect . height , contentRect . height , align ) +
80+ offset . y ,
5181 left : triggerRect . left - contentRect . width - offset . x ,
5282} ) ;
5383
@@ -63,7 +93,8 @@ export function getPosition(
6393 contentRect : DOMRect ,
6494 placement : Placement ,
6595 offset : Offset ,
96+ align : Alignment ,
6697) : Position {
67- const config = { triggerRect, contentRect, offset } ;
98+ const config = { triggerRect, contentRect, offset, align } ;
6899 return positionMap [ placement ] ( config ) ;
69100}
0 commit comments