Represents a calendar event.
Consumers map their database records to this struct before passing them
to calendar components. Only id and start are required — everything
else has sensible defaults.
End time semantics
End times are exclusive (half-open interval [start, end)).
- An all-day event on April 1st:
start: ~D[2026-04-01], end: ~D[2026-04-02] - A 1-hour meeting at 10am:
start: ~U[2026-04-01 10:00:00Z], end: ~U[2026-04-01 11:00:00Z]
If end is nil, a default duration is applied:
- All-day events default to 1 day
- Timed events default to 30 minutes
Examples
# Minimal event
%PhoenixLiveCalendar.Event{id: "1", start: ~D[2026-04-01]}
# Timed event with details
%PhoenixLiveCalendar.Event{
id: "meeting-1",
title: "Team Standup",
start: ~U[2026-04-01 09:00:00Z],
end: ~U[2026-04-01 09:30:00Z],
color: "bg-primary"
}
# All-day event spanning multiple days
%PhoenixLiveCalendar.Event{
id: "vacation-1",
title: "Spring Break",
start: ~D[2026-04-06],
end: ~D[2026-04-11],
all_day: true
}
# Booking with resource and constraints
%PhoenixLiveCalendar.Event{
id: "booking-1",
title: "Dr. Smith - Consultation",
start: ~U[2026-04-01 14:00:00Z],
end: ~U[2026-04-01 15:00:00Z],
resource_id: "room-a",
editable: false,
overlap: false,
extra: %{patient_id: "p-123", type: :consultation}
}Visibility tiers
The visibility field controls which views an event appears in.
Higher values mean the event appears in more zoomed-out views.
Uses multiples of 10 for granularity between tiers.
| Visibility | Shows in | Example use |
|---|---|---|
| 10 | Day only | Lunch breaks, focus time |
| 20 | Day + Week (default) | Regular meetings |
| 25 | Day + Week | Slightly important |
| 30 | Day + Week + Month | Key deadlines |
| 35 | Day + Week + Month | High priority |
| 40 | Day + Week + Month + Year | Company milestones |
The CalendarComponent applies view-specific thresholds automatically.
Override with min_visibility attribute on the component.
Summary
Functions
Returns whether this event is an all-day event.
Returns the duration of the event in seconds.
Returns the effective end time/date for this event.
Returns whether this event spans multiple days.
Returns whether this event falls on the given date.
Returns whether this event overlaps with the given date range [range_start, range_end).
Returns whether this event meets a minimum visibility threshold.
Types
@type display() :: :auto | :background | :inverse_background | :none
@type priority() :: :low | :normal | :high | :urgent
@type status() :: :confirmed | :tentative | :cancelled | :pending_approval | :no_show
@type t() :: %PhoenixLiveCalendar.Event{ all_day: boolean(), badge: String.t() | nil, border_color: String.t() | nil, category: String.t() | atom() | nil, class: String.t() | nil, color: String.t() | nil, description: String.t() | nil, display: display(), editable: boolean(), end: Date.t() | DateTime.t() | NaiveDateTime.t() | nil, extra: map(), group_id: term() | nil, icon: String.t() | nil, id: term(), location: String.t() | nil, overlap: boolean(), priority: priority(), recurrence_id: term() | nil, resource_id: term() | nil, resource_ids: [term()] | nil, rrule: String.t() | nil, start: Date.t() | DateTime.t() | NaiveDateTime.t(), status: status(), text_color: String.t() | nil, title: String.t() | nil, transparency: transparency(), urgency: urgency(), url: String.t() | nil, visibility: pos_integer() }
@type transparency() :: :opaque | :transparent
@type urgency() :: :none | :attention | :warning | :critical
Functions
Returns whether this event is an all-day event.
An event is considered all-day if all_day is true or if
start is a Date (not a DateTime or NaiveDateTime).
Returns the duration of the event in seconds.
For all-day events, returns the number of days multiplied by 86400.
@spec effective_end(t()) :: Date.t() | DateTime.t() | NaiveDateTime.t()
Returns the effective end time/date for this event.
If end is nil, applies a default duration:
- All-day events: start + 1 day
- Timed events: start + 30 minutes
Returns whether this event spans multiple days.
Returns whether this event falls on the given date.
@spec overlaps_range?(t(), Date.t() | DateTime.t(), Date.t() | DateTime.t()) :: boolean()
Returns whether this event overlaps with the given date range [range_start, range_end).
@spec visible_at?(t(), pos_integer()) :: boolean()
Returns whether this event meets a minimum visibility threshold.
Events with visibility >= min_visibility are considered visible.
Default event visibility is 20 (shows in day and week views).
View defaults
| View | Threshold | Shows events with visibility >= |
|---|---|---|
| Day | 10 | 10+ (almost everything) |
| Week | 20 | 20+ (default events) |
| Month | 30 | 30+ (important only) |
| Year | 40 | 40+ (highest importance) |
Examples
iex> Event.visible_at?(%Event{id: 1, start: ~D[2026-04-01], visibility: 20}, 30)
false
iex> Event.visible_at?(%Event{id: 1, start: ~D[2026-04-01], visibility: 30}, 30)
true