feat: add ZetaCalendar component and usage example#429
Conversation
- Implement ZetaCalendar widget with dual-month inline date range selection - Support initialStartDate, initialEndDate, minDate, maxDate props - Add onRangeChanged, onApply, onCancel, and onReset callbacks - Include year/month picker overlay via ZetaCalendarYearPicker - Add CalendarExample page demonstrating range selection, apply, cancel, and reset interactions
PR Checks complete
Created with Flutter code quality action |
There was a problem hiding this comment.
Pull request overview
This PR introduces a new inline, dual-month date range selection component (ZetaCalendar) to the Zeta Flutter component library, along with a year/month picker overlay and an example page demonstrating common interactions (range selection, reset, cancel, apply).
Changes:
- Added
ZetaCalendarwidget with dual-month range selection, min/max bounds, and footer actions. - Added internal calendar building blocks (
ZetaCalendarMonth,ZetaCalendarDay,ZetaCalendarYearPicker). - Added a new
CalendarExamplepage and wired it into the example app’s component routing.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 16 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/zeta_flutter/lib/zeta_components.dart | Exports the new calendar component from the library barrel. |
| packages/zeta_flutter/lib/src/components/calendar/calendar.dart | Implements the main dual-month calendar with range selection, navigation, and actions. |
| packages/zeta_flutter/lib/src/components/calendar/calendar_year_picker.dart | Adds an overlay year/month picker used by the calendar header. |
| packages/zeta_flutter/lib/src/components/calendar/calendar_month.dart | Renders a month grid and computes per-day visual states (disabled/in-range/etc.). |
| packages/zeta_flutter/lib/src/components/calendar/calendar_day.dart | Renders individual day cells with selection/range styling. |
| example/lib/pages/components/calendar_example.dart | Demonstrates calendar usage and interactions in the example app. |
| example/lib/config/components_config.dart | Registers the new Calendar example route and deferred import. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Visit the preview URL for this PR (updated for commit 52e4391): https://zeta-flutter-main--pr-429-wfcng-48025-h3saz5nu.web.app (expires Mon, 22 Jun 2026 16:31:52 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 Sign: 5ca681de0a0ad9185b252304c113355d5ee04ca6 |
…etbook Enhance `packages/zeta_flutter/lib/src/components/calendar/calendar.dart` with configurable multi-month display, initial range support, min/max bounds, range callbacks, and apply/cancel/reset actions. Add `widgetbook/lib/src/components/calendar.widgetbook.dart` use case to preview `ZetaCalendar` with knobs (including pre-selected range and month count). Add `example/lib/pages/components/calendar_example.dart` to demonstrate interactive range selection, formatted selected state, and action feedback.
…etbook Enhance `packages/zeta_flutter/lib/src/components/calendar/calendar.dart` with configurable multi-month display, initial range support, min/max bounds, range callbacks, and apply/cancel/reset actions. Add `widgetbook/lib/src/components/calendar.widgetbook.dart` use case to preview `ZetaCalendar` with knobs (including pre-selected range and month count). Add `example/lib/pages/components/calendar_example.dart` to demonstrate interactive range selection, formatted selected state, and action feedback.
…etbook Enhance `packages/zeta_flutter/lib/src/components/calendar/calendar.dart` with configurable multi-month display, initial range support, min/max bounds, range callbacks, and apply/cancel/reset actions. Add `widgetbook/lib/src/components/calendar.widgetbook.dart` use case to preview `ZetaCalendar` with knobs (including pre-selected range and month count). Add `example/lib/pages/components/calendar_example.dart` to demonstrate interactive range selection, formatted selected state, and action feedback.
thelukewalton
left a comment
There was a problem hiding this comment.
Sorry for not reviewing this yet, I have been very busy. @aygurs Please can you review and if its good merge
| if (date.isBefore(_startDate!)) { | ||
| _endDate = _startDate; | ||
| _startDate = date; | ||
| } else if (date.isAtSameMomentAs(_startDate!)) { | ||
| _startDate = null; |
| final minYearOffset = context.knobs.object.dropdown( | ||
| label: 'Min date (years from now)', | ||
| options: [-10, -5, -3, -1, 0], | ||
| labelBuilder: (value) => value == 0 ? 'Today' : '$value years', | ||
| initialOption: -5, | ||
| ); | ||
| final maxYearOffset = context.knobs.object.dropdown( | ||
| label: 'Max date (years from now)', | ||
| options: [0, 1, 3, 5, 10], | ||
| labelBuilder: (value) => value == 0 ? 'Today' : '+$value years', | ||
| initialOption: 5, | ||
| ); | ||
|
|
||
| return ZetaCalendar( | ||
| visibleMonthCount: context.knobs.object.dropdown( | ||
| label: 'Number of months', | ||
| options: [1, 2, 3], | ||
| labelBuilder: (value) => '$value', | ||
| initialOption: 2, | ||
| ), | ||
| initialStartDate: preSelect ? DateTime(now.year, now.month, 10) : null, | ||
| initialEndDate: preSelect ? DateTime(now.year, now.month + 1, 15) : null, | ||
| minDate: DateTime(now.year + minYearOffset), | ||
| maxDate: DateTime(now.year + maxYearOffset), | ||
| onRangeChanged: (range) {}, | ||
| onApply: (range) {}, | ||
| onCancel: () {}, | ||
| onReset: () {}, | ||
| ); |
| ..._buildWeeks(daysInMonth, firstWeekday, colors), | ||
| ], | ||
| ); | ||
| } | ||
|
|
||
| List<Widget> _buildWeeks(int daysInMonth, int firstWeekday, ZetaColors colors) { |
calendar_component_example.mp4