# `PhoenixLiveCalendar.CalendarComponent`
[🔗](https://github.com/mdon/phoenix_live_calendar/blob/v0.5.0/lib/phoenix_live_calendar/calendar_component.ex#L1)

The main calendar LiveComponent.

Manages internal state (current date, view mode, navigation) and renders
the appropriate view. Communicates with the parent via callback functions.

## Usage

    <.live_component
      module={PhoenixLiveCalendar.CalendarComponent}
      id="my-calendar"
      events={@events}
      on_date_select={fn date -> send(self(), {:date_selected, date}) end}
      on_event_click={fn event_id -> send(self(), {:event_clicked, event_id}) end}
    />

## Full example with all options

    <.live_component
      module={PhoenixLiveCalendar.CalendarComponent}
      id="booking-calendar"
      events={@events}
      resources={@resources}
      view={:week}
      views={[:day, :week, :month]}
      date={@current_date}
      selected_date={@selected_date}
      week_start={1}
      min_time={~T[08:00:00]}
      max_time={~T[20:00:00]}
      slot_duration={15}
      time_format={:h12}
      business_hours={@business_hours}
      translations={%{labels: %{today: "Aujourd'hui"}}}
      dir={:ltr}
      on_date_select={fn date -> send(self(), {:date_selected, date}) end}
      on_range_select={fn range -> send(self(), {:range_selected, range}) end}
      on_event_click={fn event_id -> send(self(), {:event_clicked, event_id}) end}
      on_event_drop={fn data -> send(self(), {:event_dropped, data}) end}
      on_view_change={fn data -> send(self(), {:view_changed, data}) end}
    />

## Slots

The underlying views' customization slots are forwarded through the
component — pass them as `<.live_component>` children:

    <.live_component module={PhoenixLiveCalendar.CalendarComponent} id="cal" events={@events}>
      <:event :let={event}>
        <.my_event_chip event={event} />
      </:event>
    </.live_component>

- `:event` — custom event rendering (month, week, day, N-day, agenda,
  timeline, resource)
- `:day_cell` — full month day-cell replacement (receives
  `%{date: date, events: events, markers: markers}`)
- `:time_label` — time gutter labels (week, day, N-day)
- `:resource_label` / `:resource_header` — timeline / resource column labels
- `:day_header` / `:no_events` — agenda day headings and empty state
- `:info` — toolbar info (ⓘ) disclosure content
- `:header` — replaces the ENTIRE built-in toolbar with custom chrome.
  Receives `%{title, view, date, today_date, today_visible, on_prev,
  on_next, on_today, view_options, myself}` — `on_prev`/`on_next`/
  `on_today` are ready-made `Phoenix.LiveView.JS` commands pre-targeted
  at the component, and `view_options` is an ordered list of
  `%{view, label, active?, command}` descriptors (localized labels via
  the component's `translations`), so a full switcher is one `:for`:

      <:header :let={h}>
        <button phx-click={h.on_prev}>‹</button>
        <span>{h.title}</span>
        <button phx-click={h.on_next}>›</button>
        <button
          :for={o <- h.view_options}
          phx-click={o.command}
          class={o.active? && "btn-active"}
        >
          {o.label}
        </button>
      </:header>

  `show_header={false}` suppresses the slot too (one toggle for any
  chrome). `myself` is the component's CID for custom pushes.
  Replacement is total: the `:toolbar_start`/`:toolbar_end`/`:info`
  slots render inside the STOCK toolbar only, so fold that content into
  your own chrome. The container's `rounded-lg` doesn't clip children —
  give opaque chrome `rounded-t-[inherit]` (or transparent chrome like
  the stock header) so it doesn't paint square over the top corners.

## Sizing

The calendar is an `@container`: the header and the month view compact
to the CONTAINER's width, not the viewport (the other views still key
their responsive tiers on the viewport for now). Container-query
containment strips intrinsic width, so the root carries `w-full` —
give the calendar a width-defining parent (any block/flex column
does); inside a shrink-to-fit context (inline-block, float, flex row
without a basis) a container-queried element cannot size itself by its
content.

The view area scrolls its own overflow (`.cal-view-container` is
`overflow-auto`) — EXCEPT when the month view runs with
`cell_overflow: :visible`, which trades the scroll container away so
custom day-cell tooltips can escape the grid. In a bounded-height
panel the month grid then overflows the panel instead of scrolling;
keep `:clip` (the default) where scrolling matters.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
