import * as _lucide_angular from '@lucide/angular';
import * as i0 from '@angular/core';
import { OnInit, OnDestroy, Type, EventEmitter, AfterViewInit, OnChanges, ViewContainerRef, SimpleChanges } from '@angular/core';
import { BehaviorSubject, Subject, Observable } from 'rxjs';
import { CalendarButton, CalendarEventData, CalendarEvent, CalendarView, CalendarConfig, ColumnDay, HourRow, MonthItem } from 'mn-angular-lib/calendar-core';
/**
* Main calendar orchestrator component.
*
* Provides a toolbar with view switching (month / week / day), date navigation,
* and an optional action button. The active view and an upcoming-events sidebar
* are rendered inside a responsive grid layout.
*
* All configuration (visible hours, locale, labels, mobile breakpoint) is read
* from the `mn-config.json5` system via {@link MN_CALENDAR_CONFIG}, falling back
* to the legacy {@link CALENDAR_CONFIG} injection token, then to built-in defaults.
* Date formatting is delegated to the {@link CALENDAR_DATE_FORMATTER} token.
*
* @example
* ```html
*
*
* ```
*/
declare class CalendarViewComponent implements OnInit, OnDestroy {
/** Lucide icons the template renders. */
protected readonly icons: Record<"ChevronLeft" | "ChevronRight", _lucide_angular.LucideIconData>;
/**
* Accessible name for this control. Resolved through the conventional
* `mnCalendar.calendarView` key so an app can translate it, falling back to English when the
* key is not defined rather than leaking the raw key into the UI.
*/
get calendarViewLabel(): string;
/** Whether to show the action button in the toolbar. */
showButton: boolean;
/** Label text for the action button. */
buttonTitle: string;
/** Array of buttons to display in the toolbar's top-right area. */
buttons: CalendarButton[];
/** Custom event renderer component type. */
CalendarEventComponent?: Type;
/** Observable or EventEmitter that pushes new event arrays into the calendar. */
NewCalendarItemsEvent?: EventEmitter;
/** Emits when the calendar needs fresh event data (e.g. after navigation). */
RequestNewCalendarItemsEvent: EventEmitter;
/** Emits when a calendar event is clicked. */
CalendarItemClickedEvent: EventEmitter;
/** Emits when the action button is clicked. */
ButtonClickedEvent: EventEmitter;
readonly CalendarView: typeof CalendarView;
/** Ties the view tabs to the panel they control, uniquely per calendar. */
readonly panelId: string;
currentView: CalendarView;
focusDay: Date;
viewOptions: {
value: CalendarView;
label: string;
}[];
isMobileView: boolean;
/** BehaviorSubject so late-subscribing child views receive the last emitted events. */
internalEventsChanged: BehaviorSubject;
/** Subject for broadcasting focus-day changes to child views. */
internalFocusDayChanged: Subject;
private destroy$;
protected config: CalendarConfig;
/** Reference to the injected mn-config object (mutated in-place on locale change). */
private readonly mnConfigRef;
private readonly destroyRef;
private readonly lang;
private readonly cdr;
constructor();
onResize(): void;
ngOnInit(): void;
ngOnDestroy(): void;
/** Switches the active view. On mobile, forces day view. */
switchView(view: CalendarView): void;
/**
* Names the stretch of time on screen — the day, the week, or the month. It is
* the toolbar's orientation: without it, navigating leaves you somewhere with
* no label. Announced politely, so stepping through says where you landed.
*/
get periodLabel(): string;
/** The focus day as YYYY-MM-DD, for the toolbar's date picker. */
get focusDayString(): string;
/**
* Steps the calendar by one unit of whatever is on screen: a day in day view,
* a week in week view, a month in month view. Navigating by the visible unit is
* what makes one pair of arrows serve all three.
*/
navigate(step: number): void;
/** Returns the calendar to today. */
goToToday(): void;
/**
* Handles the toolbar date picker.
* @param value The date string in YYYY-MM-DD format.
*/
onPickDate(value: string): void;
/** Handles a day click from the month view — switches to day view. */
onMonthDayClick(date: Date): void;
/** Forwards a child event click to the parent output. */
onEventClick(event: CalendarEvent): void;
/** trackBy for view option buttons. */
trackByView(_index: number, item: {
value: CalendarView;
}): string;
/** Rebuilds view options and labels from the current config. */
private rebuildFromConfig;
private checkMobileView;
/**
* Adds months without the end-of-month overflow `setMonth` alone produces —
* 31 January plus one month is 28 February, not 3 March.
*/
private addMonths;
/** Monday of the week containing `date`, matching the grid the views draw. */
private startOfWeek;
private setFocusDay;
static ɵfac: i0.ɵɵFactoryDeclaration;
static ɵcmp: i0.ɵɵComponentDeclaration;
}
/** Extended hour row with a pre-resolved display label. */
type DisplayHourRow$1 = {
hourLabel: string;
} & HourRow;
/**
* Week grid view showing 7 day columns with half-hour time slots.
*
* Overlapping events within the same day are laid out in sub-columns
* so they appear side-by-side rather than stacked.
*/
declare class CalendarWeekComponent implements OnInit, OnDestroy {
private readonly lang;
/**
* Accessible name for this control. Resolved through the conventional
* `mnCalendar.weekView` key so an app can translate it, falling back to English when the
* key is not defined rather than leaking the raw key into the UI.
*/
get weekViewLabel(): string;
private layoutService;
private cdr;
/** The date around which the week is centred. */
focusDay: Date;
/** Observable that emits the full event list whenever it changes. */
eventsChanged: Observable;
/** Observable that emits when the focus day changes. */
focusDayChanged: Observable;
/** Resolved calendar configuration passed from the parent view. */
config?: CalendarConfig;
/** Optional custom event renderer component. */
calendarEventComponent?: Type;
/** Emits when a calendar event is clicked. */
eventClicked: EventEmitter;
columns: ColumnDay[];
hourRows: DisplayHourRow$1[];
displayEvents: CalendarEvent[];
totalRows: number;
currentTimeRow: number;
currentTimeCol: string;
/** The current time, formatted for the label riding the now-line. */
currentTimeLabel: string;
gridTemplateColumns: string;
private dayColumnMap;
private events;
private destroy$;
private formatter;
private resolvedConfig;
private currentTimeInterval?;
constructor();
ngOnInit(): void;
ngOnDestroy(): void;
/** Returns the CSS `grid-row` value for an event based on its start/end times. */
getEventRow(event: CalendarEvent): string;
/** Returns the CSS `grid-column` span for a day header, accounting for sub-columns. */
getHeaderColumn(dayIndex: number): string;
/** Returns the CSS `grid-column` value for an event within its day's sub-columns. */
getEventColumn(event: CalendarEvent): string;
/** Forwards event click to parent. */
onEventClick(event: CalendarEvent): void;
/** trackBy for hour rows. */
trackByHour(_index: number, row: DisplayHourRow$1): number;
/** trackBy for day columns. */
trackByColumn(_index: number, col: ColumnDay): number;
/** trackBy for events. */
trackByEvent(_index: number, event: CalendarEvent): string;
private buildHourRows;
/** Builds the 7 day columns for the current week (Monday–Sunday). */
private buildColumns;
/** Filters, splits, and lays out events for the current week. */
private refreshEvents;
/** Computes the CSS grid-template-columns string based on per-day sub-column counts. */
private buildGridColumns;
/** Updates the current-time red line position. */
private updateCurrentTime;
static ɵfac: i0.ɵɵFactoryDeclaration;
static ɵcmp: i0.ɵɵComponentDeclaration;
}
/** Extended hour row with a pre-resolved display label. */
type DisplayHourRow = {
hourLabel: string;
} & HourRow;
/**
* Day grid view showing a single day with half-hour time slots.
*
* Shares the same layout algorithm as the week view via
* {@link CalendarEventLayoutService}.
*/
declare class CalendarDayComponent implements OnInit, OnDestroy {
private readonly lang;
/**
* Accessible name for this control. Resolved through the conventional
* `mnCalendar.dayView` key so an app can translate it, falling back to English when the
* key is not defined rather than leaking the raw key into the UI.
*/
get dayViewLabel(): string;
private layoutService;
private cdr;
/** The date to display. */
focusDay: Date;
/** Observable that emits the full event list whenever it changes. */
eventsChanged: Observable;
/** Observable that emits when the focus day changes. */
focusDayChanged: Observable;
/** Resolved calendar configuration passed from the parent view. */
config?: CalendarConfig;
/** Optional custom event renderer component. */
calendarEventComponent?: Type;
/** Emits when a calendar event is clicked. */
eventClicked: EventEmitter;
hourRows: DisplayHourRow[];
displayEvents: CalendarEvent[];
totalRows: number;
totalColumns: number;
currentTimeRow: number;
/** The current time, formatted for the label riding the now-line. */
currentTimeLabel: string;
isToday: boolean;
dayName: string;
private events;
private destroy$;
private formatter;
private resolvedConfig;
private currentTimeInterval?;
constructor();
ngOnInit(): void;
ngOnDestroy(): void;
/** Returns the CSS `grid-row` value for an event. */
getEventRow(event: CalendarEvent): string;
/** Returns the CSS `grid-column` value for an event within its sub-columns. */
getEventColumn(event: CalendarEvent): string;
/** Forwards event click to parent. */
onEventClick(event: CalendarEvent): void;
/** trackBy for hour rows. */
trackByHour(_index: number, row: DisplayHourRow): number;
/** trackBy for events. */
trackByEvent(_index: number, event: CalendarEvent): string;
private buildHourRows;
/** Updates the day name and isToday flag. */
private updateDayInfo;
/** Filters, splits, and lays out events for the focus day. */
private refreshEvents;
/** Updates the current-time red line position. */
private updateCurrentTime;
static ɵfac: i0.ɵɵFactoryDeclaration;
static ɵcmp: i0.ɵɵComponentDeclaration;
}
/**
* Month grid view showing a 7×6 grid of day cells.
*
* Each cell displays the day number and up to 3 coloured dots representing
* events on that day. Clicking a cell emits `dayClicked`.
*/
declare class CalendarMonthComponent implements OnInit, OnDestroy {
private readonly lang;
private readonly cdr;
/**
* Accessible name for this control. Resolved through the conventional
* `mnCalendar.monthView` key so an app can translate it, falling back to English when the
* key is not defined rather than leaking the raw key into the UI.
*/
get monthViewLabel(): string;
/** The date whose month is displayed. */
focusDay: Date;
/** Observable that emits the full event list whenever it changes. */
eventsChanged: Observable;
/** Observable that emits when the focus day changes. */
focusDayChanged: Observable;
/** Resolved calendar configuration passed from the parent view. */
config?: CalendarConfig;
/** Emits the date of a clicked day cell. */
dayClicked: EventEmitter;
monthItems: MonthItem[];
/** Short weekday column headers (e.g. "Mon"), kept compact for the narrow columns. */
weekdayLabels: string[];
/** Word shown after the "+N" overflow count (e.g. "more"), from config. */
moreEventsLabel: string;
private events;
private destroy$;
private formatter;
constructor();
ngOnInit(): void;
ngOnDestroy(): void;
/** Emits the clicked day's date. */
onDayClick(date: Date): void;
/** trackBy for day name headers. */
trackByDayName(index: number): number;
/** trackBy for month grid cells. */
trackByMonthItem(_index: number, item: MonthItem): number;
/** trackBy for event dots. */
trackByEventDot(_index: number, event: CalendarEvent): string;
/** Builds the 42-cell month grid (6 rows × 7 columns). */
private buildMonth;
private createMonthItem;
static ɵfac: i0.ɵɵFactoryDeclaration;
static ɵcmp: i0.ɵɵComponentDeclaration;
}
/**
* Dynamic event renderer that injects a custom or default event component
* into its view container.
*
* The component to render is resolved in this order:
* 1. `customComponent` input (set on the parent week/day view)
* 2. `event.component` (per-event override)
* 3. {@link CalendarEventDefaultComponent} (library default)
*/
declare class CalendarEventComponent implements AfterViewInit, OnChanges {
/** The event data to render. */
event: CalendarEvent;
/** Optional custom component type that overrides the default renderer. */
customComponent?: Type;
/** Emits when the rendered event is clicked. */
eventClicked: EventEmitter;
eventContainer: ViewContainerRef;
private rendered;
ngAfterViewInit(): void;
ngOnChanges(changes: SimpleChanges): void;
/** Emits the event click. */
onEventClick(): void;
/** Creates the event component dynamically and sets its `event` property. */
private renderComponent;
static ɵfac: i0.ɵɵFactoryDeclaration;
static ɵcmp: i0.ɵɵComponentDeclaration;
}
/**
* Default event renderer used when no custom component is provided.
*
* Displays the event title, formatted time range, and optional description
* with the event's colour scheme applied as background and left-border accent.
*/
declare class CalendarEventDefaultComponent implements CalendarEventData, OnInit {
private cdr;
/** The event to render. Set by {@link CalendarEventComponent} after creation. */
event: CalendarEvent;
formattedTime: string;
private formatter;
constructor();
ngOnInit(): Promise;
static ɵfac: i0.ɵɵFactoryDeclaration;
static ɵcmp: i0.ɵɵComponentDeclaration;
}
/**
* Sidebar component that lists the next 10 upcoming events
* (events whose end time is in the future), sorted by start time.
*/
declare class UpcomingEventsComponent implements OnInit, OnChanges, OnDestroy {
private readonly lang;
private readonly cdr;
/**
* Accessible name for this control. Resolved through the conventional
* `mnCalendar.upcomingEvents` key so an app can translate it, falling back to English when the
* key is not defined rather than leaking the raw key into the UI.
*/
get upcomingEventsLabel(): string;
/** Observable that emits the full event list whenever it changes. */
eventsChanged: Observable;
/** Resolved calendar configuration passed from the parent view. */
config?: CalendarConfig;
/** Emits when an upcoming event row is clicked. */
eventClicked: EventEmitter;
upcomingEvents: CalendarEvent[];
title: string;
noEventsMessage: string;
private destroy$;
constructor();
/** Re-read labels when the config input changes (e.g. after a locale switch). */
ngOnChanges(changes: SimpleChanges): void;
ngOnInit(): void;
ngOnDestroy(): void;
/** trackBy for upcoming event rows. */
trackByEvent(_index: number, event: CalendarEvent): string;
static ɵfac: i0.ɵɵFactoryDeclaration;
static ɵcmp: i0.ɵɵComponentDeclaration;
}
/**
* Renders a single row in the upcoming-events sidebar.
* Shows the event title, formatted date/time, and optional description.
*/
declare class UpcomingEventRowComponent implements OnInit {
/** The event to display. */
event: CalendarEvent;
/** Emits the event when this row is clicked. */
eventClicked: EventEmitter;
formattedDate: string;
private formatter;
/** Marks the view when the awaited time string lands (see {@link ngOnInit}). */
private readonly cdr;
constructor();
ngOnInit(): Promise;
static ɵfac: i0.ɵɵFactoryDeclaration;
static ɵcmp: i0.ɵɵComponentDeclaration;
}
/**
* How the bar arranges itself at its current width.
*
* - `inline` — the day strip and Today share one row, under the month header. The
* strip never stacks: as space runs out it shows fewer days rather than adding a
* row.
* - `compact` — too narrow even for a three-day strip, so the days give way to a
* date picker sitting beside Today, still under the month header.
*
* Resolved from the bar's own width — not the viewport — so a bar in a narrow
* sidebar lays itself out like a phone even on a wide screen.
*/
type DateSelectorBarLayout = 'compact' | 'inline';
/** Represents a single day tile in the date selector. */
type DayTile = {
/** The full date object (at midnight). */
date: Date;
/** Short day name (e.g. 'ma', 'Mon'). */
dayName: string;
/** Day-of-month number. */
dayNumber: number;
/** Short month name (e.g. 'mei', 'Jun'). */
monthName: string;
/**
* Whether this tile is the first day of a month within the visible strip. The
* days either side of it move apart, so the break is visible without a label —
* the month header above the strip names both months.
*/
startsNewMonth: boolean;
/** Whether this tile is the currently selected date. */
isSelected: boolean;
/** Whether this tile represents today. */
isToday: boolean;
/** Full, locale-formatted date used as the tile's accessible name. */
accessibleLabel: string;
};
/**
* Reusable, responsive date selector bar.
*
* Renders a "Today" button, a month header, previous/next arrows and a strip of
* day tiles. Selecting a tile or pressing "Today" emits the chosen day via
* {@link dateSelected}. The arrows only shift the visible days and never emit.
*
* Given room, the strip is a whole week running Monday to Sunday, so the weekday
* columns hold still as you page and no weekday appears twice. As the bar narrows
* it shows fewer days rather than adding a second row — a partial strip has no
* week to align to, so it slides to keep the selection in view instead. Narrower
* still, and the days give way to a date picker beside Today, which keeps every
* date reachable on a phone rather than leaving a strip too cramped to use.
*
* Selecting a day already on the strip leaves it exactly where it is; a selection
* from outside moves the strip to where that day is. The arrows page by whatever
* is on show, without touching the selection.
*
* The component carries no hard-coded copy: button, placeholder and assistive
* text are supplied through the label inputs, and day/month names follow
* {@link locale} (falling back to the active {@link MnLanguageService} locale).
*
* @example
* ```html
*
*
* ```
*/
declare class MnDateSelectorBar implements OnInit {
/** Lucide icons the template renders. */
protected readonly icons: Record<"ChevronLeft" | "ChevronRight", _lucide_angular.LucideIconData>;
/** The currently selected date, provided by the parent. */
readonly selectedDate: i0.InputSignal;
/** Label for the "Today" button. */
readonly todayLabel: i0.InputSignal;
/** Placeholder for the date picker shown in place of a too-cramped week strip. */
readonly pickDateLabel: i0.InputSignal;
/** Accessible name for the previous-week arrow. */
readonly previousLabel: i0.InputSignal;
/** Accessible name for the next-week arrow. */
readonly nextLabel: i0.InputSignal;
/** Accessible name for the day strip as a whole. */
readonly dayStripLabel: i0.InputSignal;
/**
* BCP 47 locale used to format day/month names. When empty, the active
* {@link MnLanguageService} locale is used.
*/
readonly locale: i0.InputSignal;
/** Emits when the user selects a new date. */
readonly dateSelected: i0.OutputEmitterRef;
/** Unique id for this instance's date picker, so several bars can coexist. */
readonly pickerId: string;
private readonly destroyRef;
private readonly injector;
private readonly host;
private readonly lang;
private readonly tileButtons;
/** The bar's own width in px, tracked so the layout follows its container. */
private readonly containerWidth;
/** Bumped whenever the active language changes so name formatting re-runs. */
private readonly localeTick;
/** How the bar is arranged at the current width. */
readonly layout: i0.Signal;
/** Whether the day strip is shown, or the picker has taken its place. */
readonly showDayStrip: i0.Signal;
/**
* Days in the visible strip: a full week where there's room, fewer as the bar
* narrows. The bar drops days rather than adding a second row, so it stays one
* line at every width it can.
*/
readonly tileCount: i0.Signal;
/** Effective locale: explicit input, else the active app locale. */
private readonly effectiveLocale;
/**
* First day of the visible strip — the week's Monday when a whole week is on
* show, otherwise whatever start keeps the selection in view.
*
* The strip holds still while the selection stays on screen; a selection
* outside it moves to where that day is. The arrows write here directly to page
* away from the selection.
*/
private readonly windowStart;
/**
* Index of the tile that is currently keyboard-reachable (roving tabindex).
* Tracks the selection so Tab lands on the selected day, falling back to Monday
* when the selection has been paged out of sight.
*/
private readonly focusedIndex;
/** The visible days, derived from the window start and the current selection. */
readonly dayTiles: i0.Signal;
/**
* The month the strip is currently in, spelled out for the header that titles
* the bar — so the days below are never just loose numbers. Reads as a range
* when the strip straddles two months, and carries both years when it straddles
* two of those.
*/
readonly monthCaption: i0.Signal;
/** The selected date formatted as YYYY-MM-DD for the date-picker input. */
readonly selectedDateString: i0.Signal;
/**
* Props for the compact-layout date picker. Sized to match the Today button it
* sits beside, and filling the rest of the row so it stays an easy tap target.
*/
readonly pickerProps: i0.Signal<{
id: string;
mode: "date";
placeholder: string;
size: "md";
borderRadius: "lg";
hover: boolean;
fullWidth: boolean;
}>;
ngOnInit(): void;
/** Shows the days before the visible ones, without changing the selection. */
navigatePrevious(): void;
/** Shows the days after the visible ones, without changing the selection. */
navigateNext(): void;
/** Returns to today: brings today into the strip and selects it. */
goToToday(): void;
/** Selects a date and emits it, unless it is already the selected day. */
selectDate(date: Date): void;
/**
* Handles the date-picker model change: shows the picked day's week and emits
* it (unless it is already the selected day).
* @param value The date string in YYYY-MM-DD format.
*/
onDateModelChanged(value: string): void;
/** Whether the tile at `index` is the one reachable with Tab. */
isTabbable(index: number): boolean;
/** Remembers which tile last held focus, so Tab returns to it. */
onTileFocus(index: number): void;
/**
* Moves focus across the week with the arrow keys. Running off either end turns
* the page to the neighbouring week and lands on the day that continues the run,
* so the weeks read as one continuous calendar.
*/
onTileKeydown(event: KeyboardEvent, index: number): void;
/** trackBy key for day tiles. */
trackByTile(_index: number, tile: DayTile): number;
/**
* Moves the strip by `pages` of whatever it is currently showing. Paging by the
* visible count is what keeps a full week Monday-aligned — seven days forward
* from a Monday is the next Monday.
*/
private shiftWindow;
/** Focuses the tile at `index` once the week has rendered. */
private moveFocusTo;
/** Index of the selected day within the visible week, or -1 when off-week. */
private indexOfSelected;
/**
* Where the strip should start to show `date` among `count` days: the week's
* Monday when a whole week is on show, otherwise centred on the day, since a
* partial strip has no week to align to.
*/
private anchorFor;
/**
* Returns the Monday of the week containing `date`. `getDay()` counts from
* Sunday, so the shift maps Sunday to the end of the week rather than the start.
*/
private startOfWeek;
/** Whole calendar days from `from` to `to`, ignoring time of day and DST. */
private daysBetween;
/** Tracks the bar's own width so the layout responds to its container. */
private observeOwnWidth;
/** Returns a Date object for today at midnight. */
private getToday;
/** Checks whether two dates fall on the same calendar day. */
private isSameDay;
static ɵfac: i0.ɵɵFactoryDeclaration;
static ɵcmp: i0.ɵɵComponentDeclaration;
}
export { CalendarDayComponent, CalendarEventComponent, CalendarEventDefaultComponent, CalendarMonthComponent, CalendarViewComponent, CalendarWeekComponent, MnDateSelectorBar, UpcomingEventRowComponent, UpcomingEventsComponent };
export type { DateSelectorBarLayout, DayTile };