1- import React , {
2- forwardRef ,
3- useEffect ,
4- useImperativeHandle ,
5- useRef ,
6- useState ,
7- } from "react" ;
1+ import { forwardRef , useEffect , useImperativeHandle , useRef } from "react" ;
82import useToggle from "../../hooks/useToggle" ;
93import {
104 StyledCalendarDay ,
115 StyledCalendarDays ,
126 StyledCalendarDaysFrame ,
137 StyledCalendarLayout ,
14- StyledCalendarNavigation ,
15- StyledCalendarNavigationSection ,
16- StyledNavigationButton ,
178} from "./styles" ;
189import useSystemSettings from "../../stores/systemSettingsStore" ;
1910import { BorderedAppContentHandles } from "../../components/BorderedApp/BorderedApp" ;
11+ import CalendarNavigation from "./CalendarNavigation/CalendarNavigation" ;
12+ import { useCalendar } from "./hooks/useCalendar" ;
2013
2114type CalendarHandles = BorderedAppContentHandles < HTMLDivElement > ;
15+
2216interface CalendarProps { }
2317
2418const Calendar = forwardRef < CalendarHandles , CalendarProps > ( ( _props , ref ) => {
2519 const sidebarToggle = useToggle ( ) ;
2620 const calendarRef = useRef < HTMLDivElement > ( null ) ;
21+ const calendar = useCalendar ( ) ;
2722 const [ mainColor , accentColor , fontColor ] = useSystemSettings ( ( s ) => [
2823 s . mainColor ,
2924 s . accentColor ,
3025 s . fontColor ,
3126 ] ) ;
3227
33- const now = new Date ( ) ;
34- const [ year , setYear ] = useState ( now . getFullYear ( ) ) ;
35- const [ month , setMonth ] = useState ( now . getMonth ( ) ) ;
36- const prevYear = ( ) => setYear ( ( x ) => x - 1 ) ;
37- const nextYear = ( ) => setYear ( ( x ) => x + 1 ) ;
38- const wrapMonth = ( m : number ) => ( ( m % 12 ) + 12 ) % 12 ;
39- const nextMonth = ( ) => setMonth ( ( x ) => wrapMonth ( x + 1 ) ) ;
40- const prevMonth = ( ) => setMonth ( ( x ) => wrapMonth ( x - 1 ) ) ;
41-
4228 useImperativeHandle ( ref , ( ) => ( {
4329 onParentKeyDown ( ) { } ,
4430 element : calendarRef . current ,
@@ -56,7 +42,6 @@ const Calendar = forwardRef<CalendarHandles, CalendarProps>((_props, ref) => {
5642 const entry = entries [ 0 ] ;
5743 if ( ! entry ) return ;
5844
59- // Most reliable in modern browsers
6045 const width = entry . contentRect . width ;
6146
6247 const wide = width >= 600 ;
@@ -73,105 +58,36 @@ const Calendar = forwardRef<CalendarHandles, CalendarProps>((_props, ref) => {
7358 } ;
7459 } ) ;
7560
76- const dayName = (
77- dayIndex : number ,
78- locale = "en-US" ,
79- format : "long" | "short" = "short" ,
80- ) =>
81- new Intl . DateTimeFormat ( locale , { weekday : format } ) . format (
82- new Date ( 2021 , 0 , dayIndex + 3 ) ,
83- ) ;
84- const monthName = (
85- monthIndex : number ,
86- locale = "en-US" ,
87- format : "long" | "short" = "long" ,
88- ) =>
89- new Intl . DateTimeFormat ( locale , { month : format } ) . format (
90- new Date ( 2021 , monthIndex , 1 ) ,
91- ) ;
92-
93- const buildGrid = ( ) => {
94- const daysInMonth = new Date ( year , month + 1 , 0 ) . getDate ( ) ;
95- const firstDayOfMonth = new Date ( year , month , 0 ) . getDay ( ) ; // 0 - 6
96- const calendarCellCount = 7 * 6 ; // 7 cols (1 per day), 6 rows
97-
98- const elements : React . ReactNode [ ] = [ ] ;
99-
100- for ( let i = 0 ; i < calendarCellCount ; i ++ ) {
101- const dayNumber = i - firstDayOfMonth + 1 ;
102- const cellDayName = dayName ( i + 1 ) ;
103-
104- if ( dayNumber < 1 || dayNumber > daysInMonth ) {
105- // Empty cell
106- elements . push (
107- < StyledCalendarDay
108- backgroundColor = { mainColor }
109- color = { fontColor }
110- key = { i }
111- currentMonth = { false }
112- >
113- { cellDayName }
114- </ StyledCalendarDay > ,
115- ) ;
116- } else {
117- // Valid day
118- elements . push (
119- < StyledCalendarDay
120- backgroundColor = { mainColor }
121- color = { fontColor }
122- key = { i }
123- currentMonth
124- >
125- < span > { cellDayName } </ span >
126- < span > { dayNumber } </ span >
127- </ StyledCalendarDay > ,
128- ) ;
129- }
130- }
131- return elements ;
132- } ;
133-
13461 return (
13562 < StyledCalendarLayout
13663 ref = { calendarRef }
13764 sidebarOpen = { sidebarToggle . state }
13865 className = "calendar"
13966 >
140- < StyledCalendarNavigation className = "calendar__nav" >
141- < StyledCalendarNavigationSection >
142- < StyledNavigationButton
143- className = "calendar__nav-button"
144- onClick = { prevMonth }
145- > { `<` } </ StyledNavigationButton >
146- < StyledNavigationButton className = "calendar__nav-button" >
147- { monthName ( month ) }
148- </ StyledNavigationButton >
149- < StyledNavigationButton
150- className = "calendar__nav-button"
151- onClick = { nextMonth }
152- > { `>` } </ StyledNavigationButton >
153- </ StyledCalendarNavigationSection >
154-
155- < StyledCalendarNavigationSection >
156- < StyledNavigationButton
157- className = "calendar__nav-button"
158- onClick = { prevYear }
159- > { `<` } </ StyledNavigationButton >
160- < StyledNavigationButton className = "calendar__nav-button" >
161- { year }
162- </ StyledNavigationButton >
163- < StyledNavigationButton
164- className = "calendar__nav-button"
165- onClick = { nextYear }
166- > { `>` } </ StyledNavigationButton >
167- </ StyledCalendarNavigationSection >
168- </ StyledCalendarNavigation >
67+ < CalendarNavigation
68+ month = { calendar . month }
69+ year = { calendar . year }
70+ onClickNextMonth = { calendar . nextMonth }
71+ onClickNextYear = { calendar . nextYear }
72+ onClickPrevMonth = { calendar . prevMonth }
73+ onClickPrevYear = { calendar . prevYear }
74+ />
16975 < StyledCalendarDaysFrame frameColor = { accentColor } >
17076 < StyledCalendarDays
17177 borderColor = { accentColor }
17278 className = "calendar__days"
17379 >
174- { buildGrid ( ) }
80+ { calendar . days . map ( ( { date, day, isToday, isThisMonth } ) => (
81+ < StyledCalendarDay
82+ backgroundColor = { mainColor }
83+ color = { fontColor }
84+ currentMonth = { isThisMonth }
85+ >
86+ < span > { day } </ span >
87+ < span > { date } </ span >
88+ { isToday && < span > TODAY</ span > }
89+ </ StyledCalendarDay >
90+ ) ) }
17591 </ StyledCalendarDays >
17692 </ StyledCalendarDaysFrame >
17793 </ StyledCalendarLayout >
0 commit comments