@@ -9,6 +9,7 @@ import { toast, ToastState } from './state';
99import './styles.css' ;
1010import {
1111 isAction ,
12+ Position ,
1213 SwipeDirection ,
1314 type ExternalToast ,
1415 type HeightT ,
@@ -42,6 +43,25 @@ const SWIPE_THRESHOLD = 45;
4243// Equal to exit animation duration
4344const TIME_BEFORE_UNMOUNT = 200 ;
4445
46+ // Resolve logical positions to physical ones based on text direction
47+ function resolvePosition ( position : Position , dir : 'ltr' | 'rtl' | 'auto' ) : Position {
48+ const resolvedDir = dir === 'auto' ? getDocumentDirection ( ) : dir ;
49+ const isRTL = resolvedDir === 'rtl' ;
50+
51+ switch ( position ) {
52+ case 'top-start' :
53+ return isRTL ? 'top-right' : 'top-left' ;
54+ case 'top-end' :
55+ return isRTL ? 'top-left' : 'top-right' ;
56+ case 'bottom-start' :
57+ return isRTL ? 'bottom-right' : 'bottom-left' ;
58+ case 'bottom-end' :
59+ return isRTL ? 'bottom-left' : 'bottom-right' ;
60+ default :
61+ return position ;
62+ }
63+ }
64+
4565function cn ( ...classes : ( string | undefined ) [ ] ) {
4666 return classes . filter ( Boolean ) . join ( ' ' ) ;
4767}
@@ -621,10 +641,15 @@ const Toaster = React.forwardRef<HTMLElement, ToasterProps>(function Toaster(pro
621641 return toasts . filter ( ( toast ) => ! toast . toasterId ) ;
622642 } , [ toasts , id ] ) ;
623643 const possiblePositions = React . useMemo ( ( ) => {
644+ const resolved = resolvePosition ( position , dir ) ;
624645 return Array . from (
625- new Set ( [ position ] . concat ( filteredToasts . filter ( ( toast ) => toast . position ) . map ( ( toast ) => toast . position ) ) ) ,
646+ new Set (
647+ [ resolved ] . concat (
648+ filteredToasts . filter ( ( toast ) => toast . position ) . map ( ( toast ) => resolvePosition ( toast . position , dir ) ) ,
649+ ) ,
650+ ) ,
626651 ) ;
627- } , [ filteredToasts , position ] ) ;
652+ } , [ filteredToasts , position , dir ] ) ;
628653 const [ heights , setHeights ] = React . useState < HeightT [ ] > ( [ ] ) ;
629654 const [ expanded , setExpanded ] = React . useState ( false ) ;
630655 const [ interacting , setInteracting ] = React . useState ( false ) ;
@@ -783,7 +808,10 @@ const Toaster = React.forwardRef<HTMLElement, ToasterProps>(function Toaster(pro
783808 data-react-aria-top-layer
784809 >
785810 { possiblePositions . map ( ( position , index ) => {
786- const [ y , x ] = position . split ( '-' ) ;
811+ console . log ( 'position' , position ) ;
812+ console . log ( 'dir' , dir ) ;
813+ const resolvedPos = resolvePosition ( position , dir === 'auto' ? getDocumentDirection ( ) : dir ) ;
814+ const [ y , x ] = resolvedPos . split ( '-' ) ;
787815
788816 if ( ! filteredToasts . length ) return null ;
789817
@@ -861,7 +889,7 @@ const Toaster = React.forwardRef<HTMLElement, ToasterProps>(function Toaster(pro
861889 visibleToasts = { visibleToasts }
862890 closeButton = { toastOptions ?. closeButton ?? closeButton }
863891 interacting = { interacting }
864- position = { position }
892+ position = { resolvedPos }
865893 style = { toastOptions ?. style }
866894 unstyled = { toastOptions ?. unstyled }
867895 classNames = { toastOptions ?. classNames }
0 commit comments