Skip to content

Commit 21f1c46

Browse files
committed
fix: Enhance SideEventArranger with configurable layout styles for overlapping events.
1 parent f92687e commit 21f1c46

1 file changed

Lines changed: 32 additions & 15 deletions

File tree

lib/src/event_arrangers/side_event_arranger.dart

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,36 @@
44

55
part of 'event_arrangers.dart';
66

7-
/// Arranges overlapping calendar events side by side, ensuring no visual overlap and optimal use of space.
8-
/// Supports multi-day and full-day events, fixed or dynamic width allocation, and configurable edge overlap handling.
7+
/// Arranges overlapping calendar events side by side with configurable layout styles.
98
///
10-
/// Events are grouped into columns to prevent overlaps, and each event is positioned and sized for best readability.
11-
/// Use [maxWidth] to constrain event width, and [includeEdges] to control whether touching events are treated as overlapping.
9+
/// Supports two layout modes:
10+
/// - **Expanded layout** (default): Events expand to fill available width for maximum readability
11+
/// - **Cross-event layout**: Overlapping events are positioned side-by-side with reduced width to prevent visual overlap
12+
///
13+
/// Also supports multi-day and full-day events, fixed or dynamic width allocation via [maxWidth].
14+
/// Use [useCrossEventLayout] to switch between expanded and cross-event layouts.
1215
class SideEventArranger<T extends Object?> extends EventArranger<T> {
1316
/// This class will provide method that will arrange
1417
/// all the events side by side.
1518
const SideEventArranger({
1619
this.maxWidth,
17-
this.includeEdges = false,
20+
this.useCrossEventLayout = false,
1821
});
1922

20-
/// Decides whether events that are overlapping on edge
21-
/// (ex, event1 has the same end-time as the start-time of event 2)
22-
/// should be offset or not.
23+
/// Controls the layout style for overlapping events.
24+
///
25+
/// When `false` (default): Events use expanded layout where each event takes
26+
/// full available width, creating a more spacious appearance. Events that only
27+
/// touch at edges (e.g., event1 ends at 2:00 PM, event2 starts at 2:00 PM)
28+
/// are not treated as overlapping.
2329
///
24-
/// If includeEdges is true, it will offset the events else it will not.
25-
/// Defaults to false.
26-
final bool includeEdges;
30+
/// When `true`: Events use cross-event layout where overlapping events are
31+
/// positioned side-by-side with reduced width (typically half-width), preventing
32+
/// any visual overlap. Events that touch at edges are treated as overlapping
33+
/// and will be positioned accordingly.
34+
///
35+
/// Defaults to false (expanded layout).
36+
final bool useCrossEventLayout;
2737

2838
/// If enough space is available, the event slot will
2939
/// use the specified max width.
@@ -226,15 +236,22 @@ class SideEventArranger<T extends Object?> extends EventArranger<T> {
226236
return !_eventsOverlap(event, lastEvent);
227237
}
228238

229-
/// Returns true if two events overlap in time, considering [includeEdges].
239+
/// Returns true if two events overlap in time, considering [useCrossEventLayout].
240+
///
241+
/// When [useCrossEventLayout] is `false` (expanded layout):
242+
/// - Events that only touch at edges are NOT considered overlapping
243+
/// - Example: Event A (1:00-2:00) and Event B (2:00-3:00) do NOT overlap
244+
/// - This allows events to expand and use full available width
230245
///
231-
/// If [includeEdges] is false, events that only touch at edges are not considered overlapping.
232-
/// If true, touching events are treated as overlapping.
246+
/// When [useCrossEventLayout] is `true` (cross-event layout):
247+
/// - Events that touch at edges ARE considered overlapping
248+
/// - Example: Event A (1:00-2:00) and Event B (2:00-3:00) DO overlap
249+
/// - This ensures side-by-side positioning with reduced (half) width
233250
///
234251
/// Handles edge cases like zero-duration events and identical start/end times.
235252
/// Optimized for fast arithmetic comparison.
236253
bool _eventsOverlap(_NormalizedEvent<T> event1, _NormalizedEvent<T> event2) {
237-
if (includeEdges) {
254+
if (useCrossEventLayout) {
238255
// Events overlap if they have any overlapping time (including touching edges)
239256
return event1.effectiveStartTime <= event2.effectiveEndTime &&
240257
event2.effectiveStartTime <= event1.effectiveEndTime;

0 commit comments

Comments
 (0)