Appearance topic
Appearance
This is part of the kalender documentation.
What the calendar looks like: event tiles, theming, and replacing the default components. For where tiles are placed rather than how they look, see Layout.
Tile Components
TileComponents is the primary way to control how events look in the calendar. Pass it as tileComponents to MultiDayHeader, MultiDayBody and MonthBody, the header and body widgets of the day, multi-day and month views. See Headers and bodies for passing those to KalenderView.
For schedule views, use ScheduleTileComponents instead (passed via ScheduleBody.tileComponents).
Simple tile
For most apps a plain tileBuilder is all you need:
MultiDayBody(
tileComponents: TileComponents(
tileBuilder: (context, event, tileRange) {
final myEvent = event as Event;
return Container(
decoration: BoxDecoration(
color: myEvent.color ?? Colors.blue,
borderRadius: BorderRadius.circular(4),
),
padding: const EdgeInsets.all(4),
child: Text(myEvent.title, style: const TextStyle(color: Colors.white)),
);
},
),
)
All TileComponents options
Only tileBuilder is required. Every other field defaults to null, which keeps
the package's own behavior: overlayTileBuilder, tileWhenDraggingBuilder,
feedbackTileBuilder, dropTargetTile, dragAnchorStrategy,
resizeDragAnchorStrategy, resizeHandlePositioner, verticalResizeHandle and
horizontalResizeHandle.
mergeSemantics, true by default, merges a tile's widgets into one semantics
node, the unit a screen reader announces. Set it to false when a tile holds its
own buttons or other controls.
resizeHandlePositioner places the resize handles. details carries the tile's
geometry and builds the detectors:
TileComponents(
tileBuilder: (context, event, tileRange) => Container(),
resizeHandlePositioner: (context, details) => Stack(
fit: StackFit.expand,
children: [
if (details.showStart)
Positioned(top: 0, left: 0, right: 0, height: 8, child: details.startResizeDetector),
if (details.showEnd)
Positioned(bottom: 0, left: 0, right: 0, height: 8, child: details.endResizeDetector),
],
),
)
ScheduleTileComponents
Schedule tiles take tileBuilder, tileWhenDraggingBuilder, feedbackTileBuilder, dragAnchorStrategy and mergeSemantics. The drop target is a row highlight, see ScheduleComponents.
Advanced tiles with event-tile utilities
For tiles that need to know the exact tapped time or find nearby events, use the provided mixins.
Tip
The calendar handles taps on a tile only when onEventTapped or onEventTappedWithDetail is set. Leave both unset to handle taps in your tile.
DayEventTileUtils (day / multi-day body tiles)
class CustomDayEventTile extends StatelessWidget with DayEventTileUtils {
@override
final KalenderEvent event;
@override
final KalenderDateTimeRange tileRange;
const CustomDayEventTile({
super.key,
required this.event,
required this.tileRange,
});
Event get myEvent => event as Event;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTapUp: (details) {
// Convert a local tap position into an exact DateTime.
final tappedTime = dateTimeFromPosition(context, details.localPosition);
debugPrint('Tapped at: $tappedTime');
// Find events that overlap a ±15-minute window around this one.
final nearby = nearbyEvents(
context,
before: const Duration(minutes: 15),
after: const Duration(minutes: 15),
);
debugPrint('Found ${nearby.length} nearby events');
},
child: Container(
decoration: BoxDecoration(
color: myEvent.color ?? Colors.blue,
borderRadius: BorderRadius.circular(4),
),
padding: const EdgeInsets.all(4),
child: Text(myEvent.title, style: const TextStyle(color: Colors.white)),
),
);
}
// Static factory. Pass directly to TileComponents.tileBuilder.
static Widget builder(BuildContext context, KalenderEvent event, KalenderDateTimeRange tileRange) =>
CustomDayEventTile(
event: event,
tileRange: tileRange,
);
}
const dayTileComponents = TileComponents(tileBuilder: CustomDayEventTile.builder);
Month and multi-day header tiles mix in MultiDayEventTileUtils, which has dateFromPosition in place of dateTimeFromPosition.
Theming
By default the calendar follows your app's Material 3 theme: line colors, text styles, and the rest are derived from the ambient ColorScheme and TextTheme.
To change how every calendar in the app looks, register a KalenderThemeData on your theme. Any field you leave out keeps its Material 3 default.
MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
extensions: [
KalenderThemeData(
hourLinesStyle: HourLinesStyle(thickness: 2),
timeIndicatorStyle: TimeIndicatorStyle(lineColor: Colors.pink),
),
],
),
)
Theming part of the app
Registering on ThemeData covers every calendar in the app. To theme one of
them differently, wrap it in a KalenderTheme:
KalenderTheme(
data: const KalenderThemeData(
hourLinesStyle: HourLinesStyle(thickness: 2),
),
child: KalenderView(
eventsController: DefaultEventsController(),
kalenderController: KalenderController(viewConfiguration: MultiDayViewConfiguration.week()),
),
)
The nearest one wins when they nest, and fields it leaves out fall through to
the theme registered on ThemeData, so a scope can change one thing without
restating the rest.
A KalenderTheme also reaches the tile that follows a drag.
How a style is resolved
Four layers, most specific first. Each one fills in the fields the layer above it leaves null.
- A style passed directly to a widget, which is how a custom builder styles the widget it returns (see Custom Components).
- The nearest
KalenderThemeabove the calendar. - The
KalenderThemeDataregistered onThemeData.extensions. - The Material 3 defaults.
Note
The widths of the week number column and the timeline are not styles. Set them with MonthBodyComponents.weekNumberWidth or MultiDayBodyComponents.timelineWidth.
Switching themes transitions the calendar's colors along with the rest of the app. A KalenderTheme scope does not animate.
The overflow overlay
The overlay listing a day's events, opened from the +3 button that stands in for events that do not fit or from KalenderController.showDayOverlay, is themed the same way. Its card and close button take Flutter's own CardThemeData and ButtonStyle.
KalenderThemeData(
multiDayOverlayStyle: MultiDayOverlayStyle(
cardTheme: CardThemeData(
color: Colors.white,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
),
closeButtonStyle: IconButton.styleFrom(backgroundColor: Colors.amber),
// Dims the calendar behind the card. Transparent by default.
barrierColor: Colors.black54,
width: 320,
),
)
closeButtonStyle merges over the defaults of a filled tonal icon button, so set only the fields you change.
Custom Components
Pass a KalenderComponents object to KalenderView to override the default widget builders.
Note
Every builder receives a BuildContext as its first argument and resolves what
it needs from it: styles with KalenderTheme.of(context), and the state of the
enclosing calendar with KalenderScope, one accessor per value.
MultiDayComponents
KalenderComponents(
multiDayComponents: MultiDayComponents(
headerComponents: MultiDayHeaderComponents(
dayHeaderBuilder: (context, date) => CustomWidget(),
weekNumberBuilder: (context, visibleDateTimeRange) => CustomWidget(),
leftTriggerBuilder: (context, pageWidth) => SizedBox(width: pageWidth / 20),
rightTriggerBuilder: (context, pageWidth) => SizedBox(width: pageWidth / 20),
overlayBuilders: OverlayBuilders(
multiDayPortalOverlayButtonBuilder:
(context, portalController, numberOfHiddenRows) => SizedBox(),
),
),
bodyComponents: MultiDayBodyComponents(
hourLines: (context, heightPerMinute, timeOfDayRange) => CustomWidget(),
timeline: (context, heightPerMinute, timeOfDayRange, eventBeingDragged, visibleDateTimeRange) =>
CustomWidget(),
// Sizes the timeline column, for example to fit a custom timeline's labels.
timelineWidth: (context, timeOfDayRange) => 48,
daySeparator: (context) => CustomWidget(),
timeIndicator: (context, timeOfDayRange, heightPerMinute, location) => CustomWidget(),
leftTriggerBuilder: (context, pageWidth) => SizedBox(width: pageWidth / 20),
rightTriggerBuilder: (context, pageWidth) => SizedBox(width: pageWidth / 20),
topTriggerBuilder: (context, viewPortHeight) => SizedBox(height: viewPortHeight / 20),
bottomTriggerBuilder: (context, viewPortHeight) => SizedBox(height: viewPortHeight / 20),
),
),
)
MonthComponents
KalenderComponents(
monthComponents: MonthComponents(
headerComponents: MonthHeaderComponents(
weekDayHeaderBuilder: (context, date) => SizedBox(),
),
bodyComponents: MonthBodyComponents(
monthDayHeaderBuilder: (context, date) => SizedBox(),
// Custom per-cell background, or use the ready-made
// MonthDayCell.shadeAdjacentMonths() to shade adjacent-month days.
monthDayCellBuilder: (context, details) => SizedBox(),
monthGridBuilder: (context, numberOfRows) => SizedBox(),
weekNumberBuilder: (context, visibleDateTimeRange) => SizedBox(),
leftTriggerBuilder: (context, pageWidth) => SizedBox(),
rightTriggerBuilder: (context, pageWidth) => SizedBox(),
overlayBuilders: OverlayBuilders(
multiDayPortalOverlayButtonBuilder:
(context, portalController, numberOfHiddenRows) => SizedBox(),
),
),
),
)
ScheduleComponents
KalenderComponents(
scheduleComponents: ScheduleComponents(
// The date column shown beside the first row of each day.
leadingDateBuilder: (context, date) => Container(),
// Wraps a row to highlight it as the drop target during a drag.
scheduleTileHighlightBuilder: (context, date, range, child) =>
Container(child: child),
// Optional: builder for days with no events.
emptyItemBuilder: (context, tileRange) => Container(),
// Optional: builder for the month heading rows.
monthItemBuilder: (context, monthRange) => Container(),
),
)
Classes
- DayHeader Appearance
- A widget that displays the name of the day and the day number of the week.
- DayHeaderStyle Appearance
- The style for the DayHeader.
- DayNumberStyle Appearance
-
The style of the
DayNumber. - DaySeparator Appearance
- A widget that displays a separator between days.
- DaySeparatorStyle Appearance
- The style for the DaySeparator widget.
- HourLines Appearance
- A widget that displays lines for each hour based on the timeOfDayRange and heightPerMinute.
- HourLinesStyle Appearance
- The style of the HourLines widget.
- KalenderComponents Appearance
- A class holding the widget builders used by the KalenderView.
- KalenderTheme Appearance
- Applies a KalenderThemeData to the calendars below it.
- KalenderThemeData Appearance
- The calendar's visual theme, following the same layering as Flutter's own component themes.
- MonthBodyComponents Appearance
- The component builders used by the MonthBody.
- MonthComponents Appearance
- A class containing custom widget builders for the MonthBody and MonthHeader.
- MonthDayCell Appearance
- Renders the background of a single day cell in the month body.
- MonthDayCellDetails Appearance
- Details describing a single day cell, passed to a MonthDayCellBuilder.
- MonthDayHeader Appearance
- A widget that displays the day number.
- MonthDayHeaderStyle Appearance
- The style of the MonthDayHeader.
- MonthGrid Appearance
- A widget that displays the month grid.
- MonthGridStyle Appearance
- The style of the MonthGrid.
- MonthHeaderComponents Appearance
- The component builders used by the MonthHeader.
- MultiDayBodyComponents Appearance
- The component builders used by the MultiDayBody.
- MultiDayComponents Appearance
- A class containing custom widget builders for the MultiDayBody and MultiDayHeader.
- MultiDayEventOverlayTile Appearance
- MultiDayHeaderComponents Appearance
- The component builders used by the MultiDayHeader.
- MultiDayOverlay Appearance
- MultiDayOverlayPortal Appearance
- The "+N more" button of a day. It opens the day's overlay through KalenderController.openDayOverlay.
- MultiDayOverlayStyle Appearance
- MultiDayPortalOverlayButton Appearance
- MultiDayPortalOverlayButtonStyle Appearance
- OverlayBuilders Appearance
- Builders used to create the overlayPortal, overlay and overlay button widgets.
- ResizeHandleStyle Appearance
- The style of the resize handles laid out by DefaultResizeHandles.
- ScheduleComponents Appearance
-
A class containing custom widget builders for the
ScheduleBody. - ScheduleDate Appearance
- The short day name and the day of the month shown at the start of each day in the schedule.
- ScheduleDateStyle Appearance
- The style of the ScheduleDate.
- ScheduleTileComponents Appearance
- The components used by the ScheduleBody to render the event tiles.
- ScheduleTileHighlight Appearance
- A widget that highlights the list item if the date is within the given range.
- ScheduleTileHighlightStyle Appearance
- TileComponents Appearance
- The components used by the MultiDayBody/MonthBody to render the event tiles.
- TimeIndicator Appearance
- A widget that displays the current time as a line and a circle.
- TimeIndicatorStyle Appearance
- The style of the TimeIndicator widget.
- TimeLine Appearance
- A widget that displays a list of times based on the timeOfDayRange and heightPerMinute.
- TimelineStyle Appearance
- The style of the TimeLine widget.
- WeekDayHeader Appearance
- A widget that displays the name of the day of the week.
- WeekDayHeaderStyle Appearance
- The style of the WeekDayHeader.
- WeekNumber Appearance
- A widget that displays the week number.
- WeekNumberStyle Appearance
- The style of the WeekNumber.
Mixins
- DayEventTileUtils Appearance
- Utilities for a tile built by TileComponents.tileBuilder in a day-based view.
- EventTileUtils Appearance
- MultiDayEventTileUtils Appearance
- Utilities for a tile that represents an event spanning several days, in the month view or the multi-day header.
- TimeLineUtils Appearance
- A mixin that provides utility methods for the TimeLine and HourLines widget.
Extensions
- KalenderLocale on BuildContext Appearance
- Gives a string builder access to the locale of the calendar it is building for.
Constants
- kDefaultWeekNumberWidth → const double Appearance
- The width defaultWeekNumberWidth returns when the style sets none.
Functions
-
defaultTimelineWidth(
BuildContext context, KalenderTimeRange timeOfDayRange) → double Appearance - The default TimelineWidthBuilder.
-
defaultWeekNumberWidth(
BuildContext context) → double Appearance - The default WeekNumberWidthBuilder.
Typedefs
- DateStringBuilder = String Function(BuildContext context, DateTime date) Appearance
-
Builds the text displayed for
date. - DayHeaderBuilder = Widget Function(BuildContext context, DateTime date) Appearance
- The day header builder.
- DaySeparatorBuilder = Widget Function(BuildContext context) Appearance
- The day separator builder.
- EmptyItemBuilder = Widget Function(BuildContext context, KalenderDateTimeRange tileRange) Appearance
- The builder for the empty item.
- FeedbackTileBuilder = Widget Function(BuildContext context, KalenderEvent event, Size dropTargetWidgetSize) Appearance
- The builder for the feedback tile. (When dragging)
- HiddenEventCountStringBuilder = String Function(BuildContext context, int numberOfHiddenEvents) Appearance
- Builds the text displayed on the overlay button that opens the hidden events.
- HourLinesBuilder = Widget Function(BuildContext context, double heightPerMinute, KalenderTimeRange timeOfDayRange) Appearance
- The hour lines builder.
- KalenderTimeStringBuilder = String Function(BuildContext context, KalenderTime time) Appearance
-
Builds the text displayed for
time. - MonthDayCellBuilder = Widget Function(BuildContext context, MonthDayCellDetails details) Appearance
- Builds the background of a single day cell in the month body.
- MonthDayHeaderBuilder = Widget Function(BuildContext context, DateTime date) Appearance
- The month day header builder.
- MonthGridBuilder = Widget Function(BuildContext context, int numberOfRows) Appearance
- The month grid builder.
- MonthItemBuilder = Widget Function(BuildContext context, KalenderDateTimeRange tileRange) Appearance
- The builder for the month item.
-
MultiDayOverlayBuilder
= Widget Function(BuildContext context, {required DateTime date, required List<
KalenderEvent> events, required RenderBoxCallback getMultiDayEventLayoutRenderBox, required RenderBoxCallback getOverlayPortalRenderBox, required MultiDayOverlayEventTileBuilder overlayTileBuilder, required OverlayPortalController portalController, required double tileHeight}) Appearance - A function that returns a MultiDayOverlay widget.
- MultiDayOverlayEventTileBuilder = MultiDayEventOverlayTile Function(BuildContext context, KalenderEvent event, FloatingDateTimeRange floatingRange, VoidCallback dismissOverlay) Appearance
- A function that returns a MultiDayEventOverlayTile for the multi-day overlay.
-
MultiDayOverlayPortalBuilder
= Widget Function(BuildContext context, {required DateTime date, required List<
KalenderEvent> events, required int numberOfHiddenRows, required OverlayBuilders? overlayBuilders, required double tileHeight}) Appearance - A function that returns a MultiDayOverlayPortal.
- MultiDayPortalOverlayButtonBuilder = Widget Function(BuildContext context, OverlayPortalController portalController, int numberOfHiddenRows) Appearance
- The builder used to create the button for the MultiDayPortalOverlayButton.
- ScheduleDateBuilder = Widget Function(BuildContext context, FloatingDateTime date) Appearance
- Builds the date shown at the start of each day in the schedule.
-
ScheduleTileHighlightBuilder
= Widget Function(BuildContext context, FloatingDateTime date, ValueNotifier<
FloatingDateTimeRange?> range, Widget child) Appearance - The schedule tile highlight builder.
- TileBuilder = Widget Function(BuildContext context, KalenderEvent event, KalenderDateTimeRange tileRange) Appearance
- The default builder for the event tiles.
- TileDropTargetBuilder = Widget Function(BuildContext context, KalenderEvent event) Appearance
- The builder for the drop target event tile.
- TileWhenDraggingBuilder = Widget Function(BuildContext context, KalenderEvent event) Appearance
- The builder for the event tile when dragging.
- TimeIndicatorBuilder = Widget Function(BuildContext context, KalenderTimeRange timeOfDayRange, double heightPerMinute, Location? location) Appearance
- The time indicator builder.
-
TimeLineBuilder
= Widget Function(BuildContext context, double heightPerMinute, KalenderTimeRange timeOfDayRange, ValueNotifier<
KalenderEvent?> eventBeingDragged, ValueListenable<KalenderDateTimeRange> visibleDateTimeRange) Appearance - The time line builder.
- TimelineWidthBuilder = double Function(BuildContext context, KalenderTimeRange timeOfDayRange) Appearance
- Resolves the width of the timeline gutter.
- WeekDayHeaderBuilder = Widget Function(BuildContext context, DateTime date) Appearance
- The week day header builder.
- WeekNumberBuilder = Widget Function(BuildContext context, KalenderDateTimeRange visibleDateTimeRange) Appearance
- The week number builder.
- WeekNumberWidthBuilder = double Function(BuildContext context) Appearance
- Resolves the width of the month's week number column.