@@ -154,32 +154,13 @@ fn replace_month(date: Date, month: Month) -> Date {
154154 . expect ( "invalid or out-of-range date" )
155155}
156156
157- fn gt ( lhs_month : Month , rhs_month : Month ) -> bool {
158- let lhs = lhs_month as u8 ;
159- let rhs = rhs_month as u8 ;
160- lhs > rhs
161- }
162-
163- fn nth_month_prev ( date : Date , n : u8 ) -> Option < Date > {
164- match n {
165- 0 => Some ( date) ,
166- n => {
167- let month = date. month ( ) ;
168- let nth_month: Month = month. nth_prev ( n) ;
169- let year = date. year ( ) - if gt ( month, nth_month) { 0 } else { 1 } ;
170- let max_day = nth_month. length ( year) ;
171- Date :: from_calendar_date ( year, nth_month, date. day ( ) . min ( max_day) ) . ok ( )
172- }
173- }
174- }
175-
176157fn nth_month_next ( date : Date , n : u8 ) -> Option < Date > {
177158 match n {
178159 0 => Some ( date) ,
179160 n => {
180161 let month = date. month ( ) ;
181162 let nth_month = month. nth_next ( n) ;
182- let year = date. year ( ) + if gt ( month, nth_month) { 1 } else { 0 } ;
163+ let year = date. year ( ) + if month > nth_month { 1 } else { 0 } ;
183164 let max_day = nth_month. length ( year) ;
184165 Date :: from_calendar_date ( year, nth_month, date. day ( ) . min ( max_day) ) . ok ( )
185166 }
@@ -328,6 +309,7 @@ pub struct BaseCalendarContext {
328309 today : Date ,
329310 first_day_of_week : Weekday ,
330311 enabled_date_range : DateRange ,
312+ month_count : u8 ,
331313}
332314
333315impl BaseCalendarContext {
@@ -524,6 +506,7 @@ pub fn Calendar(props: CalendarProps) -> Element {
524506 today : props. today ,
525507 first_day_of_week : props. first_day_of_week ,
526508 enabled_date_range : DateRange :: new ( props. min_date , props. max_date ) ,
509+ month_count : props. month_count ,
527510 } ) ;
528511 // Create Calendar context provider for child components
529512 use_context_provider ( || CalendarContext {
@@ -542,11 +525,18 @@ pub fn Calendar(props: CalendarProps) -> Element {
542525 return ;
543526 } ;
544527 let mut set_focused_date = |new_date: Option <Date >| {
545- let mut view_date = ( base_ctx. view_date) ( ) ;
546528 if let Some ( date) = new_date {
547- if date. month( ) != view_date. month( ) {
548- view_date = date. replace_day( 1 ) . unwrap( ) ;
529+ let min_date = ( base_ctx. view_date) ( ) . replace_day( 1 ) . unwrap( ) ;
530+ if date < min_date {
531+ let view_date = previous_month( min_date) . unwrap_or( min_date) ;
549532 ( base_ctx. set_view_date) ( view_date) ;
533+ } else {
534+ let max_date = nth_month_next( min_date, props. month_count)
535+ . unwrap_or( min_date) ;
536+ if date >= max_date {
537+ let view_date = next_month( min_date) . unwrap_or( min_date) ;
538+ ( base_ctx. set_view_date) ( view_date) ;
539+ }
550540 }
551541 }
552542 match new_date {
@@ -591,12 +581,8 @@ pub fn Calendar(props: CalendarProps) -> Element {
591581 }
592582 } ,
593583 for offset in 0 ..props. month_count {
594- CalendarView {
595- offset,
596- div {
597- ..props. attributes. clone( ) ,
598- { props. children. clone( ) }
599- }
584+ CalendarView { offset,
585+ div { ..props. attributes. clone( ) , { props. children. clone( ) } }
600586 }
601587 }
602588 }
@@ -781,6 +767,7 @@ pub fn RangeCalendar(props: RangeCalendarProps) -> Element {
781767 today : props. today ,
782768 first_day_of_week : props. first_day_of_week ,
783769 enabled_date_range : DateRange :: new ( props. min_date , props. max_date ) ,
770+ month_count : props. month_count ,
784771 } ) ;
785772
786773 // Create RangeCalendar context provider for child components
@@ -811,11 +798,18 @@ pub fn RangeCalendar(props: RangeCalendarProps) -> Element {
811798 }
812799 }
813800 let mut set_focused_date = |new_date: Option <Date >| {
814- let mut view_date = ( base_ctx. view_date) ( ) ;
815801 if let Some ( date) = new_date {
816- if date. month( ) != view_date. month( ) {
817- view_date = date. replace_day( 1 ) . unwrap( ) ;
802+ let min_date = ( base_ctx. view_date) ( ) . replace_day( 1 ) . unwrap( ) ;
803+ if date < min_date {
804+ let view_date = previous_month( min_date) . unwrap_or( min_date) ;
818805 ( base_ctx. set_view_date) ( view_date) ;
806+ } else {
807+ let max_date = nth_month_next( min_date, props. month_count)
808+ . unwrap_or( min_date) ;
809+ if date >= max_date {
810+ let view_date = next_month( min_date) . unwrap_or( min_date) ;
811+ ( base_ctx. set_view_date) ( view_date) ;
812+ }
819813 }
820814 }
821815 match new_date {
@@ -868,12 +862,8 @@ pub fn RangeCalendar(props: RangeCalendarProps) -> Element {
868862 }
869863 } ,
870864 for offset in 0 ..props. month_count {
871- CalendarView {
872- offset,
873- div {
874- ..props. attributes. clone( ) ,
875- { props. children. clone( ) }
876- }
865+ CalendarView { offset,
866+ div { ..props. attributes. clone( ) , { props. children. clone( ) } }
877867 }
878868 }
879869 }
@@ -890,7 +880,7 @@ struct CalendarViewProps {
890880 pub children : Element ,
891881}
892882
893- #[ derive( Clone , PartialEq ) ]
883+ #[ derive( Copy , Clone , PartialEq ) ]
894884struct CalendarViewContext {
895885 offset : u8 ,
896886 view_date : Signal < Date > ,
@@ -902,25 +892,17 @@ impl CalendarViewContext {
902892 self . view_date . set ( new_date) ;
903893 }
904894
905- fn sub_months ( & self , date : Date ) -> Option < Date > {
906- nth_month_prev ( date, self . offset . max ( 1 ) )
907- }
908-
909- fn add_months ( & self , date : Date ) -> Option < Date > {
910- nth_month_next ( date, self . offset . max ( 1 ) )
911- }
912-
913895 fn replace_year ( & self , date : Date , year : i32 ) -> Date {
914896 let month = date. month ( ) ;
915897 let view_month = ( self . view_date ) ( ) . month ( ) ;
916- let year = year - if gt ( month, view_month) { 1 } else { 0 } ;
898+ let year = year - if month > view_month { 1 } else { 0 } ;
917899 date. replace_year ( year) . unwrap_or ( date)
918900 }
919901
920902 fn replace_month ( & self , date : Date , month : Month ) -> Date {
921903 let view_date = ( self . view_date ) ( ) ;
922904 let new_month = month. nth_prev ( self . offset ) ;
923- let year = view_date. year ( ) - if gt ( month, view_date. month ( ) ) { 1 } else { 0 } ;
905+ let year = view_date. year ( ) - if month > view_date. month ( ) { 1 } else { 0 } ;
924906 Date :: from_calendar_date ( year, new_month, 1 ) . unwrap_or ( date)
925907 }
926908
@@ -1147,6 +1129,10 @@ pub fn CalendarPreviousMonthButton(props: CalendarPreviousMonthButtonProps) -> E
11471129 let ctx: BaseCalendarContext = use_context ( ) ;
11481130 let view_ctx: CalendarViewContext = use_context ( ) ;
11491131
1132+ if view_ctx. offset != 0 {
1133+ return rsx ! { } ;
1134+ }
1135+
11501136 // disable previous button when we reach the limit
11511137 let button_disabled = use_memo ( move || {
11521138 // Get the current view date from context
@@ -1168,7 +1154,7 @@ pub fn CalendarPreviousMonthButton(props: CalendarPreviousMonthButtonProps) -> E
11681154 let handle_prev_month = move |e : Event < MouseData > | {
11691155 e. prevent_default ( ) ;
11701156 let current_view = ( ctx. view_date ) ( ) ;
1171- if let Some ( date) = view_ctx . sub_months ( current_view) {
1157+ if let Some ( date) = previous_month ( current_view) {
11721158 ctx. set_view_date . call ( date)
11731159 }
11741160 } ;
@@ -1248,6 +1234,10 @@ pub fn CalendarNextMonthButton(props: CalendarNextMonthButtonProps) -> Element {
12481234 let ctx: BaseCalendarContext = use_context ( ) ;
12491235 let view_ctx: CalendarViewContext = use_context ( ) ;
12501236
1237+ if view_ctx. offset + 1 != ctx. month_count {
1238+ return rsx ! { } ;
1239+ }
1240+
12511241 // disable next button when we reach the limit
12521242 let button_disabled = use_memo ( move || {
12531243 // Get the current view date from context
@@ -1273,7 +1263,7 @@ pub fn CalendarNextMonthButton(props: CalendarNextMonthButtonProps) -> Element {
12731263 let handle_next_month = move |e : Event < MouseData > | {
12741264 e. prevent_default ( ) ;
12751265 let current_view = ( ctx. view_date ) ( ) ;
1276- if let Some ( date) = view_ctx . add_months ( current_view) {
1266+ if let Some ( date) = next_month ( current_view) {
12771267 ctx. set_view_date . call ( date)
12781268 }
12791269 } ;
@@ -1511,7 +1501,7 @@ pub fn CalendarGrid(props: CalendarGridProps) -> Element {
15111501 // Day name headers
15121502 for ( weekday, label) in weekday_headers( ) {
15131503 th {
1514- key: "{weekday:?}" , // Add key for efficient diffing
1504+ key: "{weekday:?}" , // Add key for efficient diffing
15151505 class: "calendar-grid-day-header" ,
15161506 { label}
15171507 }
@@ -1890,9 +1880,7 @@ fn relative_calendar_month(
18901880 } else if date > base_ctx. enabled_date_range . end {
18911881 RelativeMonth :: Next
18921882 } else {
1893- let lhs = date. month ( ) as u8 ;
1894- let rhs = current_month as u8 ;
1895- match lhs. cmp ( & rhs) {
1883+ match date. month ( ) . cmp ( & current_month) {
18961884 std:: cmp:: Ordering :: Less => RelativeMonth :: Last ,
18971885 std:: cmp:: Ordering :: Equal => RelativeMonth :: Current ,
18981886 std:: cmp:: Ordering :: Greater => RelativeMonth :: Next ,
@@ -1937,7 +1925,7 @@ fn SingleCalendarDay(props: CalendarDayProps) -> Element {
19371925 let view_date = ( view_ctx. view_date ) ( ) ;
19381926 let month = relative_calendar_month ( date, & base_ctx, view_date. month ( ) ) ;
19391927 let in_current_month = month. current_month ( ) ;
1940- let is_focused = move || base_ctx. is_focused ( date) ;
1928+ let is_focused = move || in_current_month && base_ctx. is_focused ( date) ;
19411929 let is_today = date == base_ctx. today ;
19421930 let is_unavailable = base_ctx. is_unavailable ( date) ;
19431931
@@ -2011,7 +1999,7 @@ fn RangeCalendarDay(props: CalendarDayProps) -> Element {
20111999 let view_date = ( view_ctx. view_date ) ( ) ;
20122000 let month = relative_calendar_month ( date, & base_ctx, view_date. month ( ) ) ;
20132001 let in_current_month = month. current_month ( ) ;
2014- let is_focused = move || base_ctx. is_focused ( date) ;
2002+ let is_focused = move || in_current_month && base_ctx. is_focused ( date) ;
20152003 let is_today = date == base_ctx. today ;
20162004 let is_unavailable = base_ctx. is_unavailable ( date) ;
20172005
0 commit comments