PhoenixLiveCalendar.DayMarker (PhoenixLiveCalendar v0.3.0)

Copy Markdown View Source

Represents a date-level annotation — holidays, special hours, closures, notices.

Day markers are not events. They annotate the date itself rather than occupying a time slot. They appear as visual indicators on the day cell (background color, label, icon) and can span multiple days.

Use day markers for:

  • Public holidays ("Christmas Day", "New Year")
  • Special operating hours ("Winter hours: 10am-3pm")
  • Office closures ("Office closed for renovation")
  • Seasonal notices ("Peak season — limited availability")
  • Custom date labels ("Payday", "Sprint 12 start")

Day markers can optionally override availability — e.g., a holiday marker with available: false blocks booking, while a "reduced hours" marker with custom availability windows allows booking within those reduced hours.

Examples

# Public holiday — fully closed
%DayMarker{
  id: "xmas",
  label: "Christmas Day",
  start_date: ~D[2026-12-25],
  end_date: ~D[2026-12-26],
  type: :holiday,
  color: "bg-error/20",
  icon: "🎄",
  available: false
}

# Reduced hours — bookable within modified schedule
%DayMarker{
  id: "winter-hours",
  label: "Winter Hours",
  start_date: ~D[2026-12-20],
  end_date: ~D[2027-01-05],
  type: :notice,
  color: "bg-info/10",
  description: "Reduced hours: 10am-3pm",
  availability: [
    %PhoenixLiveCalendar.Availability{
      days_of_week: [1, 2, 3, 4, 5],
      start_time: ~T[10:00:00],
      end_time: ~T[15:00:00]
    }
  ]
}

# Simple label
%DayMarker{
  id: "payday",
  label: "Payday",
  start_date: ~D[2026-04-15],
  type: :label,
  color: "bg-success/10"
}

# Heatmap tint — cell background only, no corner label chip
%DayMarker{
  id: "activity-2026-04-15",
  label: "42 minutes",
  start_date: ~D[2026-04-15],
  color: "bg-success/30",
  show_label: false
}

Styling

  • color — cell background class. When set, it becomes the day cell's background (winning over the weekend/out-of-month tint; today/selected stay visible via an inset ring). When unset, the cell falls back to the type-based tint (:holiday/:closure/:notice/:season).
  • text_color / class — applied to the corner label chip instead of the type-based chip colors. class is the chip background/extra classes, text_color the text class.
  • show_label — set false (or label: nil) to render only the cell tint with no corner chip; ideal for heatmap-style markers.

All classes are the consumer's responsibility to make Tailwind-visible (complete class names, no interpolation).

Summary

Functions

The classes for a marker's label chip: its own class/text_color when either is set, else the type-based defaults.

Returns whether this marker covers the given date.

The first custom cell color among a day's markers, or nil.

The first :dot-style heatmap marker for a day, as %{class: intensity_class, title: label} — or nil. Views render it as a small corner/inline dot instead of a cell tint.

Returns the effective end date (exclusive). Defaults to start + 1 day.

Groups markers by date for a list of dates. Returns %{Date.t() => [t()]}.

Markers that want a visible label chip (show_label and a non-nil label).

Returns all markers that cover a given date from a list.

The semantic hook class for a day's markers (cal-day-holiday / cal-day-closed / cal-day-notice / cal-day-season), or nil. Kept on the cell even when a custom color replaces the tint, so consumer CSS/tests keying off it keep matching.

Returns the number of days this marker spans.

The type-based background tint for a day's markers, or nil.

Types

marker_type()

@type marker_type() :: :holiday | :closure | :notice | :label | :season | :custom

t()

@type t() :: %PhoenixLiveCalendar.DayMarker{
  availability: [PhoenixLiveCalendar.Availability.t()] | nil,
  available: boolean(),
  class: String.t() | nil,
  color: String.t() | nil,
  description: String.t() | nil,
  end_date: Date.t() | nil,
  extra: map(),
  icon: String.t() | nil,
  id: term(),
  label: String.t(),
  show_label: boolean(),
  start_date: Date.t(),
  text_color: String.t() | nil,
  type: marker_type()
}

Functions

chip_class(arg1)

@spec chip_class(t()) :: [String.t() | nil] | String.t()

The classes for a marker's label chip: its own class/text_color when either is set, else the type-based defaults.

covers_date?(marker, date)

@spec covers_date?(t(), Date.t()) :: boolean()

Returns whether this marker covers the given date.

custom_color(markers)

@spec custom_color([t()]) :: String.t() | nil

The first custom cell color among a day's markers, or nil.

dot(markers)

@spec dot([t()]) :: %{class: String.t(), title: String.t() | nil} | nil

The first :dot-style heatmap marker for a day, as %{class: intensity_class, title: label} — or nil. Views render it as a small corner/inline dot instead of a cell tint.

effective_end_date(day_marker)

@spec effective_end_date(t()) :: Date.t()

Returns the effective end date (exclusive). Defaults to start + 1 day.

group_by_date(markers, dates)

@spec group_by_date([t()], [Date.t()]) :: %{required(Date.t()) => [t()]}

Groups markers by date for a list of dates. Returns %{Date.t() => [t()]}.

labeled(markers)

@spec labeled([t()]) :: [t()]

Markers that want a visible label chip (show_label and a non-nil label).

markers_for_date(markers, date)

@spec markers_for_date([t()], Date.t()) :: [t()]

Returns all markers that cover a given date from a list.

semantic_class(markers)

@spec semantic_class([t()]) :: String.t() | nil

The semantic hook class for a day's markers (cal-day-holiday / cal-day-closed / cal-day-notice / cal-day-season), or nil. Kept on the cell even when a custom color replaces the tint, so consumer CSS/tests keying off it keep matching.

span_days(marker)

@spec span_days(t()) :: pos_integer()

Returns the number of days this marker spans.

type_tint(markers)

@spec type_tint([t()]) :: String.t() | nil

The type-based background tint for a day's markers, or nil.