kalender 0.26.0
kalender: ^0.26.0 copied to clipboard
A highly customizable calendar widget with day, multi-day, month and schedule views, drag-and-drop rescheduling, event resizing, and timezone support.
0.26.0 #
See MIGRATION.md for what to change.
Breaking Changes #
- The style fields on
CalendarComponentsare removed, as their 0.25.0 deprecation named:monthComponentStyles,multiDayComponentStyles,scheduleComponentStylesandoverlayStyles, along with their constructor andcopyWithparameters and their places in==andhashCode. UseKalenderThemeData, orKalenderThemeto scope it to one calendar. The builder fields stay. - The seven style container classes those fields reached go with them:
MonthComponentStyles,MonthBodyComponentStyles,MonthHeaderComponentStyles,MultiDayComponentStyles,MultiDayBodyComponentStyles,MultiDayHeaderComponentStylesandScheduleComponentStyles.OverlayStylesstays, sinceMultiDayOverlayPortalBuildernames it. eventLayoutStrategy,generateMultiDayLayoutFrameandeventSnapStrategyare classes rather than function typedefs, each with value equality and named factories for the built-ins:EventLayoutStrategy.overlap()and.sideBySide(),MultiDayLayoutStrategy.byDuration(), andEventSnapStrategy.interval(). A function cannot be deprecated into a class, so there is no window. #380HorizontalConfiguration.generateMultiDayLayoutFrameis renamed tomultiDayLayoutStrategyand is no longer nullable. It defaults toMultiDayLayoutStrategy.byDuration(), whichnullselected before.CalendarEvent.copyWithis removed. OverridecopyWithDatainstead and rebuild only what your subclass adds. The calendar callswithDateTimeRange, which applies that hook and then restoresid,interaction,multiDayRuleandisAllDaythroughcarryOver. A missing hook is reported by@mustBeOverriddenat analysis time and by a debug assert on the first drag. Your owncopyWithis no longer an override, so it can take whatever parameters suit you.CalendarEvent.interactionandCalendarEvent.multiDayRuleare getters rather than fields. Reading either is unchanged, and neither was assignable before.HourLines.fromContextno longer takes astyleargument. It resolved the style from the theme and discarded what was passed.timelineStyleis unaffected.
Behavior Changes #
- A custom component builder receives the theme-resolved style rather than an empty one, so
style?.textStyle ?? myFallbackreaches the theme value where it used to reach the fallback. Read the fields you want to override rather than falling back on null. This affectsdayHeaderBuilder,daySeparator,hourLines,monthDayHeaderBuilder,monthGridBuilder,timeIndicator,timeline,weekDayHeaderBuilder,weekNumberBuilderandleadingDateBuilder. MultiDayOverlayPortalBuilderreceives a populatedOverlayStyles, built by the newOverlayStyles.fromContext.KalenderThemeData.weekNumberStyle.alignmentreaches the month week number, which ignored it before. The month still sits at the top by default, so only a calendar that set a non-default alignment moves. #423- A custom
weekNumberBuilderreceives the same resolved style in the month header as in the month body. #423
Features #
CalendarEvent.isAllDayplaces an event in the multi-day header lane whatever its duration, with noMultiDayRuleconsulted. It defaults to false, leaves the date range untouched, is carried across drags and resizes bycarryOver, and takes part inlayoutEqualsandhashCode.PageIndexCalculatorand its subclasses are exported.ViewConfiguration.pageIndexCalculatorreturns the type, which an app had no way to name. #444EventSnapStrategy.none()leaves a dragged event where the cursor is.defaultMultiDayFrameGeneratorstays public, so a customMultiDayLayoutStrategycan reuse the built-in row assignment and change only the order events are placed in.metais a direct dependency at^1.9.0, the version that introduced@mustBeOverridden.
Deprecations #
TimeOfDayRange.isAllDayis renamed tocoversWholeDayand will be removed in 0.27.0. It reports whether the range runs from 00:00 to 23:59, and the old name is wanted forCalendarEvent.isAllDay.TimeOfDayRange.allDay()is unchanged.
Fixes #
MultiDayViewConfiguration.weekand.workWeekhonournumberOfDays. Both built their page index calculator with a hardcoded 7 and 5, so the body laid outnumberOfDayscolumns under a header showing a full week, and every column sat out of line with its header. Both take 1 through 7, which shortens the page and leaves the weekly pagination alone.copyWithcarries the value, where it reset it to the default before. #444- The month week number gutter and the multi-day timeline are measured once above both the header and the body, so the two halves cannot be given different widths. A
KalenderThemescoped to one half moved it and left the other behind, which put every day column out of line with its header. A scopedweekNumberStyleortimelineStylethe calendar has to ignore is now reported in debug builds. - The week number label is centred when the visible range crosses a week boundary. The gutter is sized by the timeline rather than by the label, so
32 - 33wraps and the short second line sat against the leading edge. #427 - A custom
multiDayOverlayBuilderormultiDayPortalOverlayButtonBuilderreceives the style resolved from the theme. - The overlay styles are resolved once, where a custom overlay builder needs them, rather than at four call sites in the header and the month body.
MultiDayOverlayPortal.overlayStylesis optional, where null leaves each overlay widget to resolve its own. - The Material defaults are built once per
ThemeDatarather than on everyKalenderTheme.ofcall, which runs on nearly every widget build. The cache is keyed weakly on the theme. - A schedule row resolves the theme only when it reads one of the two styles that need it.
MultiDayBodyConfiguration.keepPagesAlivetakes part in==andhashCode, so changing only that value reaches the calendar.MonthBodyConfigurationandMultiDayHeaderConfigurationno longer compare equal to each other, and the same for the twoVerticalConfigurationsubclasses. The base==tested onlyother is HorizontalConfigurationwith no runtime type check.MultiDayViewConfiguration.nowCallbackis included inhashCode, where it already took part in==.
Tests #
- Added coverage for the copy contract: a moved event keeps the identity, interaction and rule its subclass never mentions, the copy is the subclass's own type, a subclass with no hook is named by the assert, and the events controller still finds a dragged event by its id.
- Added coverage for
multiDayOverlayPortalBuilder, which had none, across theOverlayboundary it is built into. - Added coverage that a
KalenderThemescoped to the body cannot move the month week number gutter or the multi-day timeline away from what the header reserves, and that an ignored scoped value is reported once rather than on every frame. - Added coverage that the drag target's gutter spacer matches the drawn gutter and that the timeline labels fit the box measured for them.
- Added equality coverage for the three strategy classes.
- Added coverage for a shortened week: the page length, that the pagination stays weekly, that
copyWithcarries the value, and that the header renders that many day headers.
0.25.0 #
See MIGRATION.md for what to change.
Breaking Changes #
CalendarEvent.isMultiDayEventis removed. It was deprecated in 0.24.0, which named this release. UsespansMultipleDays(location:, defaultRule:). See MIGRATION.md. #410
Features #
KalenderThemeis a widget, so a theme can be applied to part of the tree instead of the whole app. Wrap a calendar inKalenderTheme(data: ..., child: ...)and two calendars in one app can look different. The nearest one wins when they nest, and fields it leaves out still come from theKalenderThemeDataregistered onThemeData.extensions, which keeps working as before. It is anInheritedTheme, so the theme also reaches the tile that follows a drag, which is built into anOverlayrather than below the calendar. #414- The style classes and
KalenderThemeDataareDiagnosticable, so their resolved values appear in the Flutter devtools inspector and intoString()instead of a bare instance hash. Fields left unset are omitted rather than printed as null. #412
Deprecations #
- The style fields on
CalendarComponentsare deprecated and are removed in 0.26.0. UseKalenderThemeDatafor the whole app, or aKalenderThemeto scope one calendar. The same thirteen styles were reachable both ways, andmultiDayOverlayStylehad four different homes.CalendarComponentskeeps its builder fields. See MIGRATION.md. #416
Fixes #
- Styling the month view's week number no longer moves it to the middle of its row. The top alignment came from a default on
MonthBodyComponentStyles, so setting any week number style there replaced it. The month body now applies that alignment under your style, and keeps it unless you set an alignment of your own. In the month view aKalenderThemeDatacannot change this alignment, because the style the month body passes to the widget takes precedence over the theme. The rest ofWeekNumberStyleresolves from the theme as usual. #416 #419 CalendarComponents, the containers reached through it,TileComponentsandScheduleTileComponentscompare by value, andCalendarComponentscan beconst. The inherited widgets carrying them reported a change on every rebuild because they compared by identity, and now report one only when something differs. #409CalendarComponentsand the containers reached through it gaincopyWith. #409
Tests #
- Added coverage for the scoped
KalenderTheme: it applies below itself, takes precedence over the extension, and fills in from it field by field. The nearest scope wins when they nest, two calendars in one app can be themed differently, changing the data notifies dependents where an equal value does not, andwrapcarries the theme into a tree built outside the calendar. #414 - Added
Diagnosticablecoverage for every style class: a style reports the fields it sets and omits the ones it does not, and the theme reports the styles it carries. #412 - Added equality coverage for
CalendarComponents, the containers reached through it andTileComponents: each field breaks equality when it differs, a builder held as a top-level function stays equal across instances, and one written as a closure does not. #409 - Added coverage that the month week number sits at the top of its row by default, and that a style set for the month keeps that alignment when it does not mention one. #416
- Added the
KalenderThemeDatacoverage no test reached:hashCode, the fields==compares after the third, and onecopyWithfallback. #408 - Added coverage that the time indicator follows the day while the app runs: it moves to the next column when the day rolls over, a rebuild every 30 seconds does not stop the day being noticed, a full day passing moves it off a page it no longer belongs to, and resuming the app corrects it after time passed. #413
0.24.0 #
See MIGRATION.md for what to change.
Breaking Changes #
- kalender no longer re-exports the whole
timezonepackage.LocationandTZDateTimeare still exported. Everything else, includinggetLocationandinitializeTimeZones, now needspackage:timezoneimported directly. #375 - The seven string builders deprecated in 0.23.0 are removed from the component style classes. Their replacements on the matching
*Componentsclasses are unchanged. See MIGRATION.md for the mapping. #372 MonthDayHeaderStyle.textStyleis removed. It never had any effect. The day number is styled bynumberTextStyle. #372- Three long-deprecated members are removed.
CalendarCallbacks.onMultiDayTappedwas never called, so deleting it changes nothing.DateTimeExtensions.monthNameEnglishanddayNameEnglishare replaced bymonthNameLocalized('en')anddayNameLocalized('en'). #374 EventsController.eventsFromDateTimeRangetakes a requiredmultiDayRule. This only affects code implementingEventsController. Pass the view configuration's rule. #371CalendarEvent.spansMultipleDaystakes a requireddefaultRulealongsidelocation. A subclass overriding it must widen its signature to match. #371ScheduleTileComponentsno longer acceptsdropTargetTile,overlayTileBuilderorresizeDragAnchorStrategy. None of them had any effect. Delete the arguments. To style the drop target, useScheduleComponents.scheduleTileHighlightBuilderandScheduleTileHighlightStyle. #381ScheduleTileComponents.emptyItemBuilderandmonthItemBuilderare moved toScheduleComponents. Set them onCalendarComponents.scheduleComponentsinstead. Signatures and defaults are unchanged. See MIGRATION.md. #383CalendarInteraction.throttleMillisecondsis removed. Drag updates are now combined into one per frame and follow the display's refresh rate. Nothing replaces it. Delete the argument. #368DragTargetUtilitiescan only be applied to aState. It suppliescontextandmounteditself instead of requiring them from the host. A class applying the mixin to aStateneeds no change. Anything else no longer compiles. #368
Features #
- Dragging a multi-day event down over the body keeps moving its drop target in the header, instead of freezing it until the cursor returns. Releasing over the body applies the date and keeps the time of day and duration. #369
MultiDayRuledecides which events belong in the multi-day header rather than the day timeline. Set it once on the view configuration.MultiDayRule.minimumDurationat 24 hours is the default and matches the previous behavior.MultiDayRule.calendarDaystreats anything crossing midnight as multi-day. A single event can override the rule withCalendarEvent.multiDayRule. #367 #371 #376- In debug builds, a drag or resize asserts that the event's
copyWithforwardedidandmultiDayRule.copyWithtakes no parameter for either, so an override that omits them drops them on every copy, silently until selection or multi-day placement goes wrong. The message names the subclass and the argument to add. #367
Deprecations #
CalendarEvent.isMultiDayEventis replaced byspansMultipleDays(location:). The getter measured calendar days in UTC. It will be removed in 0.25.0. See MIGRATION.md. #367
Fixes #
- View configurations built with the same arguments compare equal, so a rebuild no longer recreates the view controller and its layout caches.
PageIndexCalculatorandScheduleViewConfigurationhad no==. At 50 events a day, five rebuilds went from 105 vertical layout computations to none. #404 ViewConfiguration.nowCallbacktakes part in==. Pass a top-level or static function. #404CalendarViewattaches to a replacedcalendarControllerinstead of staying on the old one. #404CalendarInteractionandHorizontalConfigurationcompare every field in==. Four fields were missing, so changing only one of them never updated the calendar. #364CalendarSnappingcompares and copieseventSnapStrategy. Changing only the strategy had no effect, andcopyWithreset it todefaultSnapStrategy. Pass a top-level or static function. #402- Dragging to create an event no longer reacts to a drag that started on a different calendar. #366
ScrollTriggerConfiguration.copyWithkeepsscrollAmountinstead of resetting it to the default. #366MultiDayViewConfiguration.copyWithandMonthViewConfiguration.copyWithkeepmultiDayRuleinstead of resetting it to the default, and take a parameter to change it.MonthViewConfiguration.copyWithalso keepsnowCallbackand no longer takes aneventPaddingparameter, which set nothing. #387- Removing an event no longer throws when its date index was never populated for that location. #366
- Tapping the trailing edge of an event tile resolves to the last visible day instead of one day past it. #366
- The two drag-target guards that decide whether an event may be dropped in the header or the body now use the calendar's location, so they agree with the rest of the calendar near midnight and across daylight saving changes. #367
- A calendar whose locale has no intl data loaded now names the locale, the
initializeDateFormatting()call to add and the library it comes from, instead of throwing intl'sLocaleDataExceptionfrom inside a build. #382 TileComponents.overlayTileBuilderis used again by the tiles in the multi-day overflow overlay. It had been ignored since 0.14.0. #381- The vertical layout delegate returns layout data for every event, even when two events share a hash code. The layout cache is keyed by that hash, so events sharing one previously left a tile with no layout data.
CalendarEvent.hashCodeis built fromid,start,end,interactionandmultiDayRule, so this needs a customEventsControllerthat gives two events the sameid. #370
Tests #
- Added equality coverage for the configuration classes: every field of
VerticalConfigurationandHorizontalConfigurationbreaks equality when it differs, two configurations built from the same arguments compare equal, andnowCallback,initialTimeOfDayandinitialHeightPerMinutetake part. #364 #404 - Added
copyWithround-trip coverage for the view and body configurations, so a field that is not being changed survives the copy. #366 #387 - Added coverage that the vertical layout delegate returns one entry per child when two events share a hash code, including a subclass whose
hashCodeignores the id, and when the cache is already warm. #370 - Added coverage that a drag or resize asserts when the event's
copyWithdropsidormultiDayRule, and stays silent for an override that forwards both. #367 - Added coverage that
TileComponents.overlayTileBuilderrenders the overflow overlay tiles, and falls back totileBuilderwhen it is not set. #381 - Added coverage that drag moves arriving within one frame coalesce into a single update, that the update uses the newest move, and that a move queued at the moment of the drop is discarded. #368
- Added coverage for the multi-day rule on the view configurations, and that dragging a multi-day tile into the body keeps moving its header preview. #367 #369 #371
0.23.0 #
Nothing in this release stops existing code from compiling. See MIGRATION.md for what to change.
Behavior Changes #
Each of these changes what an unchanged calendar renders.
- The overflow button is labelled
+3instead of3 more, with the number formatted for the calendar's locale so locales with their own numerals read correctly. #349 - The schedule view abbreviates day names with
DateFormat.Einstead of cutting the full name at three characters, which was only correct in English. German readsMirather thanMit. #354 MonthDayHeaderStyle.stringBuilderwas declared but never called. Its replacement is wired up, so a calendar that set the old field will now see the day number change. #349MonthBodyComponents.overlayBuildersdefaults to null, soCalendarComponents.overlayBuildersapplies in the month view instead of being shadowed by an empty default. The builder-side twin of the style-side fix in 0.22.0. #349
Deprecations #
Both are removed in 0.24.0.
- The seven string builders moved from the component style classes to the matching
*Componentsclasses and gained aBuildContextparameter, so a custom builder can read the calendar's locale. The old fields still apply when the new one is not set. #349 MonthDayHeaderStyle.textStylehas never had any effect.MonthDayHeaderrenders only a day number, styled bynumberTextStyle. #354
Features #
context.calendarLocalereads the locale of the enclosing calendar, which is not necessarily the app's. #349EventsControllergainedreplaceEvents, which swaps the whole event set in one call.DefaultEventsControllerdoes it atomically: a single notification and no intermediate empty state, which suits reloading events from a source such as an imported.icsfile. The base class provides a default that clears then adds, so custom controllers keep working unchanged. #344
Fixes #
- The overflow button is now attributed to the day its events are on in right-to-left layouts. The layout frame orders its columns by text direction, but read them back as if they always ran left to right, so every button landed on the mirrored date. In a right-to-left month view with events on Wednesday the 29th, the buttons appeared on the 30th and 31st.
MultiDayLayoutFramegained an optionaltextDirection, which defaults to left to right, so a custom frame generator is unaffected. #334
0.22.0 #
Features #
MultiDayOverlayStylegainedcardTheme,closeButtonStyle,barrierColor,width, andheaderHeight, so the overlay card, its close button, and the area behind it can be styled to match the rest of the app. The card and button take Flutter's ownCardThemeDataandButtonStyle. All of them default to null, so the stock appearance is unchanged. #325- The date in the overlay header no longer looks like a button that does nothing when tapped, and it is highlighted when it is today, like the day number in every other view. #325 #328
- The today highlight is now tonal in every view, instead of grey. It is drawn with a disabled button so that it is not tappable, and a disabled button paints itself in the disabled colors, which made the highlight read as "unavailable" rather than "today". The day header, month day header, schedule date, and multi-day overlay all share one implementation now, so they cannot drift apart. #328
Fixes #
- The month view now uses the overlay builders and styles set on
monthComponents/monthComponentStylesinstead of letting the globalCalendarComponents.overlayBuildersandoverlayStylesshadow them. This matches whatCalendarComponentsdocuments and what the multi-day header already did. Only apps that set both are affected. #323 - The multi-day overlay card no longer runs past the bottom of the view and gets clipped. It was positioned without being measured, so only its top and sides were clamped, which showed up when a day low in the month grid had more events than fit. The card now stays inside the view on all four sides, and its event list scrolls when the card would be taller than the view. #324
0.21.0 #
Features #
- All component style classes (
DayHeaderStyle,TimelineStyle,HourLinesStyle, and the rest) now supportcopyWith,merge,lerp, and value equality. This is groundwork for the upcoming theme extension. #314 - Added
KalenderThemeData, aThemeExtensionwith one field per component style, andKalenderTheme.of(context), which resolves it against centralized Material 3 defaults. Register it onThemeData.extensionsto style every calendar in the app, with animated theme changes supported. #315 - The component widgets now resolve their appearance as widget style over theme extension over Material 3 defaults, so a registered
KalenderThemeDatatakes effect everywhere. Two defaults changed on purpose: the time indicator line uses the color scheme's error color instead of always red, and the day number text in the month body and schedule view defaults tobodyMediuminstead of being unstyled. #316 - The month view's day number now has a small margin so the today highlight floats clear of the gridline above and the event tiles below. The margin and the button size can be adjusted through the new
MonthDayHeaderStyle.marginandMonthDayHeaderStyle.buttonSizefields. #320
Fixes #
MultiDayOverlayStyle.eventPaddingis now applied to each event in the overlay. It was ignored, andeventsPaddingwas used for both the event list and each individual event. #316
0.20.0 #
Features #
- Multi-day and all-day events now render in the free-scroll view as a single tile spanning the day columns, instead of being split at each page boundary. They support the same interactions as the paged headers: create by dragging across the header, reschedule, resize, auto-scroll when a drag reaches the viewport edge, right-to-left layout, and the "+N more" overflow. #78 #297 #298 #299 #300 #301
Fixes #
PageTriggerConfiguration.triggerWidthis now applied. It was accepted but ignored, andcopyWithdropped it, so the edge strip that starts a page change while dragging was alwayspageWidth / 50. That is still the default, but it can now be set. #302- Fixed free-scroll multi-day events disappearing after scrolling back to a day before the event's start. The multi-day layout cache is keyed by date range and is shared across the free-scroll band's moving window, so a window cached before an event existed kept returning an event-less frame. Changing events now clears the whole cache instead of only the visible window. #306
- Fixed an event jumping to a neighbouring day when resizing it by its top or bottom edge. The resize handle anchored the drag to the column's edge, so the smallest sideways movement flipped the day. It now follows the pointer, so a small drift no longer changes the day while a deliberate drag across columns still does. #312
Tests #
- Added free-scroll multi-day coverage: spanning tiles render as one tile and stay single while scrolling, create-by-drag, reschedule and edge auto-scroll work in the band, right-to-left renders and scrolls the right way, and the "+N more" overflow opens. #297 #298 #300 #301
- Added coverage that dragging an event to the viewport edge advances the page in the paged header and body, and scrolls the body vertically. #302 #304
- Added coverage that a free-scroll multi-day event stays visible when scrolling back to windows that were cached before the event was created. #306
- Added coverage that resizing an event's bottom edge with a small horizontal drift keeps it on its own day. #312
0.19.1 #
Features #
- Added
MultiDayBodyConfiguration.keepPagesAlive(defaultfalse). When enabled, each visited multi-day page is kept alive and reused, so navigating back to it skips rebuilding every event tile. It is opt-in because cached pages stay in memory for the lifetime of the view. #293
Fixes #
- Fixed back-to-back events (one ending exactly when the next begins) rendering as overlapping at some zoom levels. An event's top and bottom now come from one shared time-to-pixel conversion, so touching tiles line up exactly instead of splitting on a rounding difference. #291
Performance #
- Sped up multi-day frame generation. #289
- The
visibleEventsnotifier now only publishes when the set of visible events actually changes, avoiding redundant work for listeners. #290 - The day view now builds only the event tiles within the visible scroll window (plus an overscan margin) instead of every event of the day, and skips the resize-handle scaffolding when resizing is disabled. #292
Tests #
0.19.0 #
Breaking Changes #
monthDayHeaderBuildernow receives a localized wall-clockDateTimeinstead of a UTC-flaggedInternalDateTime, matchingdayHeaderBuilder. #248- Replaced
ViewConfiguration.initialDateSelectionStrategywith per-dimension view-transition options:dateTransitionon all views, andscrollTransition/zoomTransitiononMultiDayViewConfiguration, each with an optional resolver for custom logic. #249 - View switches now preserve the vertical scroll (time-of-day) and zoom by default instead of resetting to
initialTimeOfDay; opt out withScrollTransition.reset/ZoomTransition.reset. #249 - Renamed
EmptyDayBehavior.showTodaytoEmptyDayBehavior.showOnlyToday, since it shows only today among empty days. #253 - Replaced
MultiDayBodyComponents.prototypeTimeLinewith atimelineWidthbuilder that returns the gutter width directly (double). The multi-day body, header and drag overlay now share this one width, so customizing the timeline can no longer misalign the header. Removed thePrototypeTimelinewidget andPrototypeTimeLineBuilder. #180
Features #
- Added
restorePerViewtransitions so each view can reopen its own last date, scroll, and zoom. #249 - Added
CalendarController.visibleTimeOfDayand theCalendarCallbacks.onScrollPositionChangedcallback. #249 - Added
ScheduleBodyConfiguration.leadingWidthto control the schedule view's date-column width. #253 - Added
TimelineStyle.widthto set an explicit multi-day timeline gutter width. #180 - Added
MonthBodyComponents.monthDayCellBuilderto style individual month-view day cells. Each call reports the cell's date, whether it is today, and whether it falls in the focused month (so adjacent-month days can be styled differently). Also added the ready-madeMonthDayCell.shadeAdjacentMonths()builder, which shades leading/trailing adjacent-month days. Pass acoloror let it default to a low-opacityonSurfaceoverlay that greys them out. #140 - Added
eventPaddingtoMonthBodyConfiguration(forwarded from the constructor and throughcopyWith), so month event tiles can be spaced likeMultiDayHeaderConfigurationalready allows. #252
Fixes #
- Fixed schedule view event tiles not lining up; every row now shares a fixed-width leading column whether or not it shows a date. #253
- Fixed the continuous schedule view scrolling to the wrong position when today has no events; the initial scroll and
animateToDateTimenow target today, or the nearest day when it is hidden. #253 - Fixed the free-scroll multi-day header "wobbling" (re-animating its height) whenever a calendar item changed; its paged content now keeps its state across rebuilds instead of being rebuilt from scratch. #282
- Fixed the free-scroll multi-day header clipping days that have more events than the leading day; the header now sizes to the tallest day currently in view. #283
- Fixed the multi-day/week header drifting out of alignment with the body when the timeline used a custom
stringBuilderor width; the gutter width now has a single source. #180 - The timeline gutter width now accounts for the text scale factor, so it no longer under-sizes when text is enlarged. #180
- The timeline gutter now measures every label across the day rather than a single sample, so a custom label format whose widest entry is not at 23:59 no longer clips. #180
Tests #
- Added end-to-end
CalendarViewregression coverage for the time indicator, run across the timezone matrix. #261 - Added end-to-end
CalendarViewtoday-highlighting coverage, run across the timezone matrix. #254 #251 - Added continuous schedule regression coverage for row alignment and the no-events-today scroll target. #253
- Added end-to-end month-view regression coverage for a custom
generateMultiDayLayoutFrame. #235 - Added regression coverage that the free-scroll header keeps its paged content's state across rebuilds. #282
- Added regression coverage that the free-scroll header fits the tallest visible day rather than only the leading page. #283
- Added regression coverage that the multi-day header and body day columns stay aligned across custom label formats, explicit widths, and right-to-left. #180
- Added regression coverage that a selected month-view event's focus aligns to its own row. #233
- Added coverage that
monthDayCellBuilderis invoked per day with the correct focused-month flags, and thatMonthDayCell.shadeAdjacentMonths()shades only the adjacent-month days. #140
0.18.7 #
Fixes #
- Fixed a blank page when a
displayRangespanned exactly one month, and the same off-by-one page count that dropped the final in-range page in the week, custom multi-day, and paginated schedule views. #266 - Fixed the month view showing a "+N more" overflow button when there were no events, and on very short row heights. Added end-to-end regression coverage. #255
0.18.6 #
Features #
- Added optional month-view week numbers via
MonthViewConfiguration.showWeekNumbers, with customizableMonthBodyComponents.weekNumberBuilderandMonthBodyComponentStyles.weekNumberStyle.
Fixes #
- Fixed a month-view regression where the
dropTargetTilepreview could fail to render while resizing an event.
0.18.5 #
Fixes #
- Fixed an issue where the highlighted selection border (
dropTargetTile) was painted on the wrong tile or missing entirely in month view overlapping events and the "X more" overflow drop-down. - Fixed a bug where the
TimeIndicatorwould disappear when zooming the calendar before any page navigation had occurred.
0.18.4 #
0.18.3 #
Fixes #
ResizeHandleandResizeHandlesnow take alengthparameter to provide properly sizedDraggablefeedback widgets instead of an empty layout, improving the resizing feedback.
0.18.2 #
Features #
TapDetailfrom*WithDetailcallbacks now calculates the exactDateTimeunder the cursor or finger tap based on spatio-temporal position within the event UI, rather than returning the event's start time.
0.18.1 #
Features #
- Added support for secondary gestures (right-clicks) on empty calendar spaces:
onSecondaryTapped,onSecondaryLongPressedand theirWithDetailvariants. - Added support for secondary gestures (right-clicks) on events:
onEventSecondaryTappedandonEventSecondaryTappedWithDetail.
Fixes #
- Fixed an issue where
DayDetailandMultiDayDetailexposed internalInternalDateTimeandInternalDateTimeRangeobjects without timezone offsets applied. All tap details now correctly apply.forLocation()to expose wall-clock DateTimes to consumers. - Fixed some raw callbacks (
onLongPressed,onSecondaryLongPressed) leaking internal representations instead of.forLocation()adjusted ones.
0.18.0 #
Features #
- New
NowCallbacktypedef andViewConfiguration.nowCallbackfield to decouple the time indicator, today highlighting, and schedule empty-day logic from the calendar's configuredLocation. InternalDateTime.isToday()now accepts an optionalDateTime? nowparameter, allowing callers to override what "today" means.DayHeader,MonthDayHeader, andScheduleDatereadnowCallbackfrom the view configuration and use it for today highlighting. When set, it takes priority over theLocation-based check.EmptyDayBehavior.showTodayinScheduleBodynow respectsnowCallback.- Added static
todayKeyconstants onDayHeader,MonthDayHeader, andScheduleDatefor easier widget-test assertions.
Fixes #
- TimeOfDay extensions (incorrect copyWith)
- Week and DayHeaders returning InternalDateTime
- Resize handle dragAnchorStrategy
- CalendarEvent passed to builders (sometimes outdated)
Tests #
- Added unit tests for
InternalDateTime.isToday(now:)parameter. - Added widget tests for
nowCallback-driven today highlighting acrossDayHeader,MonthDayHeader, andScheduleDate. - Added widget tests for time indicator positioning with
nowCallback.
0.17.0 #
Breaking Changes #
ResizeHandlePositionertypedef now takes an additionalbool isImpreciseparameter.ResizeHandlesabstract class now requires anisImpreciseconstructor parameter.
Features #
- New
InputModeenum (auto,precise,imprecise) onCalendarInteractionreplaces platform-based mobile/desktop detection for resize handle behavior. - Resize handle positioning and visibility is now driven by input precision (mouse/stylus/trackpad vs touch) instead of platform (
iOS/Android). InputMode.auto(default) detects input type dynamically — hover triggers precise mode, selection triggers imprecise mode.- New
allowHorizontalImpreciseResizeoption onCalendarInteractionto opt-in to horizontal resize handles for touch input (disabled by default). CalendarInteraction.resolveIsImprecise()provides a way to query the resolved input mode.- Removed direct
isMobileDeviceusage from resize handle widgets.
0.16.0 #
Breaking Changes #
CalendarEventis no longer generic. Thedatafield and<T>type parameter have been removed. Custom data should now be added by extendingCalendarEventdirectly.- Event IDs changed from
inttoString. This affectsaddEvent(returnsString),addEvents(returnsList<String>),removeById,byId, and any code that stores or compares event IDs. EventTile.eventIdis now aString.MultiDayOverlayEventTilerenamed toMultiDayEventOverlayTile.EventsControllerfolder moved into thecontrollersfolder; update any direct imports.
Features #
CalendarEventis now extensible. Attach custom fields (title, color, etc.) by sub-classing and overridingcopyWith. See the updated examples for guidance.CalendarEventgained alayoutEqualsmethod used internally for optimized layout rebuilds.
Fixes #
fix:SnapPoints calculation.fix:Visible events not updating correctly after a change.fix:Pointer events now pass through the time indicator widget.- Various bugs uncovered by the expanded test suite.
Improvements #
EventLayoutDelegateCacheis now cleared automatically whenheightPerMinutechanges.eventsFromDateTimeRange— thelocationparameter is no longer required.- Vertical drag-target behavior improved.
DefaultEventsControlleris now exported fromkalender.dartdirectly.
Tests #
- Extensive test additions and refactoring across controllers, layout delegates, drag targets, interactions, view configurations and callbacks.
- Added a tool (
tool/test_timezones_linux.dart) for running the test suite under multiple timezones on Linux.
Contributors #
CalendarEventextensibility,EventsControlleras a full interface, and event/group ID migration toStringcontributed by RedDuality.
0.15.0 #
- feat: Added timezone support.
- feat: Use
linked_pageviewpackage for linked scrolling between multi-day header and body. PR #247 - fix: Wrong current date highlighting due to extension method issues. PR #260 / #251
- fix: Schedule body rendering issue.
- fix: SnapPoints calculation.
- fix:
EventLayoutDelegateCachenot being cleared whenheightPerMinutechanges. - fix:
MultiDayViewControllernow correctly exposes a page offset listener.
Breaking Changes #
- Added InternalDateTime and InternalDateTimeRange classes accessible through
kalender/extensions.dart. - Moved
asUtcandasLocalextensions to InternalDateTime. EventLayoutStrategynow takes aInternalDateTimeinstead of a DateTime.GenerateMultiDayLayoutFramenow takes aInternalDateTimeRangeinstead of a DateTime.CalendarEventstores start and end times in utc format.- Removed initial date from
CalendarControllerthis is now set in theViewConfigurationof theCalendarWidget. **** - Replaced
visibleDateTimeRangeUtcvalueNotifier in theCalendarControllerwith a nullableinternalDateTimeRange. (visibleDateTimeRangeis remains the same). - The
EventsController.eventsFromDateTimeRangenow usesInternalDateTimeRangeand takes a nullableLocationfrom the timezone package. - Changes to the
DefaultDateMapto accommodate different timezones, any custom implementations will need to be updated. EventTileUtilsmixin was also updated to use the new internal date time classes.PageNavigationFunctionswas renamed toPageIndexCalculatorand updated to use internal date time classes.- Multiple default components where updated to use the new internal date time classes instead of date time classes.
- ViewConfiguration renamed
selectedDatetoinitialDateTime. CalendarHeaderandCalendarBodyno longer takeValueNotifiersand will instead create and dispose ValueNotifiers created from values passed to them.
0.14.3 #
- feat: Made TextAlign and TextOverflow configurable for TimelineStyle. PR #242 Thanks to quaaantumdev
- fix: Various issues while dragging events on multi-day view. PR #240 Thanks to redninjacat.
- fix: Drag and drop issues. PR #238 Thanks to redninjacat.
- fix: erroneous warning in month_body PR #237 Thanks to redninjacat.
0.14.2 #
- fix: Tile and ResizeHandleWidget rebuild issues.
0.14.0 #
- feat: Custom onWillAcceptWithDetails functions for DragTargets. #213
API Change #
- Resize Handles are now only rendered when the cursor is hovering on a tile or when a tile is selected on mobile.
- Added a [ResizeHandles] abstract widget and [DefaultResizeHandles] widget that allows for more customization.
- Replaced vertical/horizontal resize handle positioners from [TileComponents] with a single [ResizeHandlePositioner].
0.13.0 #
- feat: Improved TimeLine and HourLines widgets. #216
- feat: Improved DayHeader and DayHeaderStyle. PR #218
- feat: Improved CalendarCallbacks. #133 / #30
- Added
onTappedWithDetail,onLongPressedandonLongPressedWithDetailcallbacks. - DeprecatedonMultiDayTapped. (UseonTappedWithDetailinstead). - Not providingonEventTappedandonEventTappedWithDetailwill remove internal gesture detectors for events, removing interference for GestureDetectors added to EventTileBuilders. - Added mixins (DayEventTileUtilsandMultiDayEventTileUtils) for EventTileBuilders that have their own gesture detectors. - AddedonEventCreateWithDetailas used in the new advanced example. - fix: DayDragTarget
calculateLocalCursorPosition, add scroll offset after converting to local coordinate space.
0.12.0 #
- feat: Added
eventComparatortodefaultMultiDayFrameGeneratorthanks to captaingerhard. PR #210
0.11.1 #
0.11.0 #
0.10.0 #
- feat: Added locale property to CalenderView allowing users to specify a language with the intl package. #172
- feat: Add string builder to MultiDayPortalOverlayButtonStyle for easy override of the text. #172
- fix: MultiDayPortalOverlayButtonStyle not using style overrides. #172
- fix: Overlap when scrolling. #174
- fix: ScheduleView reload issues. #170
0.9.0 #
0.8.0 #
Features #
- Reimplemented schedule view. discussion 122, #130
- The tile builder is no longer a required parameter, default tiles are now provided. (Highly recommended to override these.)
0.7.2 #
0.7.1 #
0.7.0 #
Features #
- Ability to limit the number of events in MultiDayHeader. #141 / #147
MultiDayHeaderConfigurationChanges:- Added
maximumNumberOfVerticalEvents - Added
generateMultiDayLayoutFrame
- Added
- Added
overlayBuilderstoMultiDayHeaderComponentsfor customizing the overlay.
- MonthBody limits the number of events displayed based on size constraints. #141 / #147
- Added
overlayBuilderstoMonthBodyComponentsfor customizing the overlay.
- Added
- Added a new callback
OnEventTappedWithDetail. #141 / #148
Migrations #
- Deprecated MultiDayEventLayoutStrategy this should be migrated to use the new
GenerateMultiDayLayoutFrame
Improvements #
- The
defaultMultiDayGenerateFrameimproves on thedefaultMultiDayLayoutStrategyby allowing events to fill empty spaces.
Fixes #
0.6.7 #
0.6.6 #
- fix: MultiDayHeaderWidget layout regressions.
- Added widget tests for MultiDayHeaderWidget.
0.6.5 #
- fix: SingleDayView RenderFlex overflow.
0.6.3 #
- fix: Event snapping not always working.
0.6.1 #
- Changed
VerticalTileResizeHandlePositionerto never use more than 1/4 of the height of the event tile on desktop.
0.6.0 #
- Package will use Semantic versioning from 0.6.0 onwards.
Breaking changes #
- The
EventsControlleris now an abstract class, useDefaultEventsControllerinstead. - The
ViewConfigurationno longer contains the configuration forinteractionandsnapping. These are now separate classes that are passed directly to theBody/Header.
What's new #
- There is a new callback
onTappedinCalendarCallbacks.- This is now called when the user taps on an empty space a calendar (Multiday body).
- There is a new callback
onMultiDayTappedinCalendarCallbacks.- This is called when the user taps on an empty space in the calendar (Multiday Header / Month body).
- MultiDayBodyConfiguration added
horizontalPaddingthis padding is located between events and the edge of day. - There is now a
CalendarInteractionandCalendarSnappingclass that can be passed to theCalendarBody/CalendarHeaderas a ValueNotifier. This allows the calendar view to change these behaviors without rebuilding the entire view. CalendarSnappingnow has aeventSnapStrategythat can be used to define custom snapping behavior when creating new events. #119
Fixes #
Boring stuff #
- Lots of new unit tests that run in multiple timezones to ensure there are no regressions.
- Example directory layout has changed.
0.5.0 #
Breaking changes: #
Version 0.5.0 has quite a few Breaking changes, there is no easy way to migrate to this version. Here are a few important things that have changed.
-
The CalendarView now takes a
headerCalendarHeader andbodyCalendarBody widgets. You can wrap these widgets in other widgets to style them as seen here -
Event tiles now make use of the Draggable widget provided by flutter. Take a look at the TileComponents for more details on how tiles work now. This opens some interesting possibilities for displaying multiple calendars.
-
The CalendarCallbacks (previously
CalendarEventHandlers) have been changed so more information is given when an interaction occurs. -
The schedule view has been removed, but will be reimplemented in the future.
What's new #
- Auto scroll/paging (https://github.com/werner-scholtz/kalender/issues/75 && https://github.com/werner-scholtz/kalender/issues/64)
- Calender can now accept Draggable's (https://github.com/werner-scholtz/kalender/issues/48)
- More information for the TileBuilder (https://github.com/werner-scholtz/kalender/issues/83)