fluent_ui icon indicating copy to clipboard operation
fluent_ui copied to clipboard

Add WinUI3 CalendarView widget

Open Asmitta-01 opened this issue 10 months ago • 2 comments

This PR is adding the CalendarView widget to the package.

Pre-launch Checklist

  • [x] I have updated CHANGELOG.md with 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

Asmitta-01 avatar Jun 17 '25 19:06 Asmitta-01

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 ? 😓

Asmitta-01 avatar Jun 20 '25 16:06 Asmitta-01

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.

Asmitta-01 avatar Jun 20 '25 16:06 Asmitta-01

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.

bdlukaa avatar Jun 22 '25 04:06 bdlukaa

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.

bdlukaa avatar Jun 22 '25 18:06 bdlukaa

I just did a quick check:

image

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.

image

These dates should actually not exist:

image

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.

WinXaito avatar Jun 23 '25 10:06 WinXaito

Before my commit:

image

(The selected date was 1.nov.2006), so a 3 years gap.

After my commit:

image

(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.

WinXaito avatar Jun 23 '25 21:06 WinXaito

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 avatar Jun 23 '25 22:06 Asmitta-01

@Asmitta-01 you should follow the latest specs. The image you provided is from Windows 10.

bdlukaa avatar Jun 24 '25 01:06 bdlukaa