Add WinUI3 CalendarView widget
This PR is adding the CalendarView widget to the package.
Pre-launch Checklist
- [x] I have updated
CHANGELOG.mdwith my changes - [x] I have run "dart format ." on the project
- [x] I have added/updated relevant documentation
The widget works like the one in WinUI demo software but i noticed some points that might be seen:
- Add an animation when switching display modes
- Make the Decade and year display mode to be scrollable
I want to know if there're other issues
My main feedback is scrolling. I see PageView was used to make scrolling possible, but it doesn't match or mimic the native counterpart behavior.
I had an issue with PageView so instead i built a full list for the calendar(now in a ListView) and i use the offset to determine the currenth month. But i still have issues: The ListView seems heavier (i want to display 1000 weeks) and the listener on it works sometimes. For example 1000 weeks = 19 years(19.23) but my list have no limit (i even reached 1680 one time). I know the main issue may be might code but i want to leave ListView now.
I want to go back PageView. Setting pageSnapping to false makes the scrolling feel like native but i have duplicated rows. Any suggestion to improve it ? 😓
We will want to use the same resources as native. You can access all the color resources using FluentTheme.of(context).resources.[resource name]. The resources also provide sizing, padding and margins of the control. The goal is to have it as close as native as possible.
I used those vars but some of the ones specified in microsoft specs are missing in the package.
I think the solution to the scrolling behavior is making an infinite scroll list in both dimensions. It is possible with Flutter using a CustomScrollView: https://github.com/flutter/flutter/issues/20608. I am experimenting with this.
I changed the scrolling widget from PageView to a CustomScrollView. With the way a calendar work, with dates overlapping months, a page view isn't the ideal solution here. Instead of a page view, I used two grid views, creating an infinite scrolling view for both directions: up and down (https://github.com/flutter/flutter/issues/20608), which creates a negative and a positive index for the children, which allow us to calculate the date based on the index and the anchor date. In the end we got a much closer-to-native experience with enhanced performance.
Additionally, I exposed CalendarViewState, which exposes the navigation methods:
final calendarKey = GlobalKey<CalendarView>();
CalendarView(
key: calendarKey,
)
calendarKey.currentState?.firstDayOfWeek; // Gets the first day of the week
calendarKey.currentState?.visibleDate; // Get the current visible date, whether by scrolling or navigating
calendarKey.currentState?.navigateToMonth(date); // Navigates to a specific month.
calendarKey.currentState?.stepMonth(offset: 1); // Steps a month by offset
calendarKey.currentState?.navigateToYear(date); // Navigates to a specific year
calendarKey.currentState?.stepYear(offset: 1); // Steps a year by offset
We may consider adding a controller or a listener that allows listening to the current visible date, which is constantly updated by scrolling.
From this point, only the decades view needs a rework.
I just did a quick check:
This view is not scrollable, I don't know why some years are disabled. And when I click on a year, for example 2018, it show me 2013 (the one that was selected when I got to that view).
There is some incoherence between the button and scroll. I suspect that because of a miscalculation with leap years (that have 29th of february) and some speciality, like 4th-15th october 1582.
These dates should actually not exist:
That the change from Julian to Gregorian calendar.
See that:
https://github.com/user-attachments/assets/63e24698-947c-4050-b883-1f5b40563097
Edit: about the julian/gregorian calendar: https://github.com/flutter/flutter/issues/129270
I think it is not that a big deal.
However, the disruptance between scroll / buttons / header is definitly one. As I say, I'm pretty sure there is a milcalculation with leap years.
Before my commit:
(The selected date was 1.nov.2006), so a 3 years gap.
After my commit:
(The selected date is 1.jun.2001) so we are right.
It came from the approximate calculation with row per month (I work with days instead) and a spacing (2 pixels) and a wrong extend in the list.
In this image blackout dates seem disabled, like out-of-scope dates but in the specs they're strikethrough. I don't know which one we should follow.
I talk about it because i think you're working on the scolling issue(don't know if we should on it separately).
@Asmitta-01 you should follow the latest specs. The image you provided is from Windows 10.