Interaction topic
Interaction
This is part of the kalender documentation.
What the user can do inside a view: create, reschedule, resize, snap and zoom. Reacting to what they did is separate, see Controllers & Callbacks.
Interaction & Snapping
interaction sets what the user may do. KalenderHeader and KalenderBody both
accept it, so a calendar can allow different things in its header than in its
body. snapping is accepted by KalenderBody only, and only the multi-day body
reads it.
Both blocks below show every option at its default value.
KalenderBody(
interaction: KalenderInteraction(
allowResizing: true,
allowRescheduling: true,
allowEventCreation: true,
// Tap on desktop, long-press on mobile, when left unset.
createEventGesture: EventInteractionGesture.tap,
// The gesture that starts modifying an existing event, same defaults.
modifyEventGesture: EventInteractionGesture.tap,
// Input mode affects resize handle positioning and visibility:
// auto: detects dynamically from pointer events
// precise: mouse, stylus, trackpad (full-width handles, hover-to-show)
// imprecise: touch/finger (corner handles, selection-to-show)
inputMode: InputMode.auto,
// Opt in to horizontal resize handles in imprecise/touch mode.
allowHorizontalImpreciseResize: false,
),
snapping: KalenderSnapping(
snapIntervalMinutes: 10,
snapToTimeIndicator: true,
snapToOtherEvents: true,
snapRange: const Duration(minutes: 15),
eventSnapStrategy: const EventSnapStrategy.interval(),
),
)
Snapping strategies
eventSnapStrategy decides where a dragged event lands. EventSnapStrategy.interval(), the default, snaps to the nearest multiple of snapIntervalMinutes. EventSnapStrategy.none() leaves the cursor position alone. snapToTimeIndicator and snapToOtherEvents apply either way.
For anything else, extend EventSnapStrategy and override snap. Compare on runtimeType in ==, as Layout describes for the layout strategies and for the same reason.
Locking a single event
KalenderInteraction applies to the whole calendar. To hold one event in place
while the rest stay editable, give it an EventInteraction. Anything the event
forbids stays forbidden even where the calendar allows it.
KalenderEvent(
start: range.start,
end: range.end,
// Movable, but its start and end are fixed.
interaction: EventInteraction(
allowStartResize: false,
allowEndResize: false,
allowRescheduling: true,
),
)
EventInteraction.allowNone() makes an event fully read-only, and
EventInteraction.allowAll() is the default every event gets. A subclass passes
it through with super.interaction, as in Custom Events.
Zoom
Zoom the calendar in and out by changing the heightPerMinute value on the MultiDayViewController. The web_demo example shows a full implementation with ZoomDetector.
Here is a minimal example of driving zoom from Ctrl+scroll on desktop. PointerScrollEvent and HardwareKeyboard are not exported by material.dart, so both imports are needed:
import 'package:flutter/gestures.dart';
import 'package:flutter/services.dart';
class ZoomableCalendar extends StatelessWidget {
final KalenderController kalenderController;
final Widget child;
const ZoomableCalendar({
super.key,
required this.kalenderController,
required this.child,
});
@override
Widget build(BuildContext context) {
return Listener(
onPointerSignal: (event) {
if (!HardwareKeyboard.instance.isControlPressed) return;
if (event is! PointerScrollEvent) return;
final viewController = kalenderController.viewController;
if (viewController is! MultiDayViewController) return;
final heightPerMinute = viewController.heightPerMinute;
final delta = event.scrollDelta.dy.sign * -0.1;
heightPerMinute.value = (heightPerMinute.value + delta).clamp(0.5, 2.0);
},
child: child,
);
}
}
Wrap your KalenderView with this widget to enable Ctrl+scroll zooming.
Classes
- DefaultResizeHandles Interaction
- The default layout for the resize handles of an event tile.
- EventInteraction Interaction
- The EventInteraction class defines the interaction settings for individual calendar events.
- EventSnapStrategy Interaction
- Decides where a dragged event lands, given the position of the cursor.
- IntervalSnapStrategy Interaction
- Snaps to the nearest multiple of the snap interval.
- KalenderInteraction Interaction
- The KalenderInteraction class defines the interaction settings for the calendar.
- KalenderSnapping Interaction
- The KalenderSnapping class defines the snapping settings for the calendar.
- NoSnapStrategy Interaction
- Returns the cursor position unchanged.
- PageTriggerConfiguration Interaction
- The configuration for the page triggers.
- ResizeDetector Interaction
- The draggable that detects a resize gesture, wrapping the handle widget from TileComponents.verticalResizeHandle or TileComponents.horizontalResizeHandle.
- ResizeHandleDetails Interaction
- What a ResizeHandlePositioner needs to lay out the resize handles of one event tile.
- ScrollTriggerConfiguration Interaction
- The configuration for the scroll triggers.
Mixins
-
DragTargetUtilities<
T extends StatefulWidget> Interaction - Shared drag-target behaviour for the calendar's DragTarget states.
Constants
- kDefaultNewEventDuration → const Duration Interaction
- kDefaultSnapStrategy → const EventSnapStrategy Interaction
- The strategy a calendar uses when nothing overrides it.
Enums
- EventInteractionGesture Interaction
- The EventInteractionGesture is used to differentiate between the different ways to create and modify an event.
- InputMode Interaction
- The InputMode defines the type of input the calendar should optimize for.
- ResizeDirection Interaction
- The ResizeDirection is used to differentiate between the different directions that an event can be resized in.
Typedefs
- HorizontalTriggerWidgetBuilder = Widget Function(BuildContext context, double pageWidth) Interaction
- The trigger widget builder, should be constrained in width.
-
OnWillAcceptWithDetailsHorizontal
= bool Function(DragTargetDetails<
Object?> details, KalenderController controller, HorizontalConfiguration configuration) Interaction - The callback for when a drag target is evaluating whether to accept a draggable.
-
OnWillAcceptWithDetailsVertical
= bool Function(DragTargetDetails<
Object?> details, KalenderController controller, VerticalConfiguration configuration) Interaction - The callback for when a drag target is evaluating whether to accept a draggable.
- ResizeHandlePositioner = Widget Function(BuildContext context, ResizeHandleDetails details) Interaction
- The builder that positions the resize handles of an event tile.
- VerticalTriggerWidgetBuilder = Widget Function(BuildContext context, double pageWidth) Interaction
- The trigger widget builder, should be constrained in height.