@open-rlb/ng-bootstrap 3.3.16 → 3.3.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@ import { input, booleanAttribute, output, viewChild, ChangeDetectionStrategy, Co
3
3
  import * as i2$1 from '@angular/router';
4
4
  import { RouterLink, RouterLinkActive, RouterModule } from '@angular/router';
5
5
  import { Collapse, Carousel, Dropdown, Modal, Toast, Offcanvas, ScrollSpy, Popover, Tooltip } from 'bootstrap';
6
- import { NgTemplateOutlet, NgClass, formatDate, TitleCasePipe, JsonPipe, CommonModule } from '@angular/common';
6
+ import { NgTemplateOutlet, formatDate, NgClass, TitleCasePipe, JsonPipe, CommonModule } from '@angular/common';
7
7
  import { Subject, of, map, shareReplay, take, filter, switchMap, Subscription, debounceTime, distinctUntilChanged, Observable, lastValueFrom, takeUntil } from 'rxjs';
8
8
  import * as i2 from '@angular/cdk/layout';
9
9
  import * as i1 from '@angular/forms';
@@ -2513,10 +2513,43 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
2513
2513
  args: [{ selector: 'rlb-fab', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ButtonComponent], template: "<button rlb-button [color]=\"color()\" [disabled]=\"disabled()\" [outline]=\"outline()\"\n class=\"fab-button d-flex align-items-center justify-content-center\" [class]=\"[sizeClass(), positionClass()]\">\n <ng-content></ng-content>\n</button>", styles: [".fab-button{border-radius:50%;box-shadow:0 4px 12px #00000040;z-index:1050;transition:transform .2s ease,box-shadow .2s ease;padding:0}.fab-button:hover{transform:scale(1.08);box-shadow:0 6px 18px #00000059}.fab-button:active{transform:scale(.95)}:host{width:fit-content;display:block}.fab-xs{width:32px;height:32px;font-size:1rem}.fab-sm{width:44px;height:44px;font-size:1.2rem}.fab-md{width:56px;height:56px;font-size:1.4rem}.fab-lg{width:68px;height:68px;font-size:1.7rem}.fab-bottom-right{bottom:24px;right:24px}.fab-bottom-left{bottom:24px;left:24px}.fab-top-right{top:24px;right:24px}.fab-top-left{top:24px;left:24px}\n"] }]
2514
2514
  }], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], outline: [{ type: i0.Input, args: [{ isSignal: true, alias: "outline", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }] } });
2515
2515
 
2516
- function isSameDay(a, b) {
2517
- return a.yearUTC === b.yearUTC &&
2518
- a.monthUTC === b.monthUTC &&
2519
- a.dayUTC === b.dayUTC;
2516
+ const MS_PER_DAY = 86_400_000;
2517
+ /**
2518
+ * NOTE on date-tz: the getters (`.hour`, `.minute`, `.day`, `.dayOfWeek`, ...)
2519
+ * and `toString()` are timezone-aware (they add `timezoneOffset` to the raw
2520
+ * timestamp), but the mutators `set()`, `add()` and `stripSecMillis()` are
2521
+ * timezone-NAIVE — they decompose/recompose the raw timestamp as if it were
2522
+ * UTC. So `set(0, 'hour')` zeroes the UTC hour, not the local one.
2523
+ *
2524
+ * For calendar layout we need timezone-aware day math, so the helpers below
2525
+ * derive day boundaries and intra-day offsets from the tz-aware side of the
2526
+ * library instead of from `set()/add()`.
2527
+ */
2528
+ /** Returns the IANA timezone resolved from the browser/runtime. */
2529
+ function getBrowserTimezone() {
2530
+ return Intl.DateTimeFormat().resolvedOptions().timeZone;
2531
+ }
2532
+ /** Epoch ms of local midnight (in `timezone`) of the day containing `d`. */
2533
+ function startOfDayTs(d, timezone) {
2534
+ const local = d.cloneToTimezone(timezone);
2535
+ const localMs = local.timestamp + local.timezoneOffset;
2536
+ return Math.floor(localMs / MS_PER_DAY) * MS_PER_DAY - local.timezoneOffset;
2537
+ }
2538
+ /** Minutes elapsed since local midnight (in `timezone`) for `d`. */
2539
+ function minutesSinceMidnight(d, timezone) {
2540
+ const local = d.cloneToTimezone(timezone);
2541
+ return local.hour * 60 + local.minute;
2542
+ }
2543
+ /** Local-midnight instance (in `timezone`) for the day at index `offsetDays` from `d`. */
2544
+ function dayAt(d, timezone, offsetDays = 0) {
2545
+ const baseMidnight = startOfDayTs(d, timezone);
2546
+ // Re-floor after the raw day shift so DST transitions can't drift the result.
2547
+ const shifted = new DateTz(baseMidnight + offsetDays * MS_PER_DAY, timezone);
2548
+ return new DateTz(startOfDayTs(shifted, timezone), timezone);
2549
+ }
2550
+ function isSameDay(a, b, timezone) {
2551
+ const tz = timezone ?? getBrowserTimezone();
2552
+ return startOfDayTs(a, tz) === startOfDayTs(b, tz);
2520
2553
  }
2521
2554
  function addDays(date, days) {
2522
2555
  return new DateTz(date.add(days, 'day'));
@@ -2525,20 +2558,12 @@ function startOfMonth(date) {
2525
2558
  const d = new DateTz(date);
2526
2559
  return d.set(1, 'day');
2527
2560
  }
2528
- // export function endOfMonth(date: IDateTz): DateTz {
2529
- // const d = new DateTz(date.timestamp, 'UTC');
2530
- // return d.add(1, 'month').set(1, 'day').add(-1, 'day');
2531
- // }
2532
- function isToday(date) {
2533
- const today = getToday();
2534
- return date.yearUTC === today.yearUTC &&
2535
- date.monthUTC === today.monthUTC &&
2536
- date.dayUTC === today.dayUTC;
2561
+ function isToday(date, timezone) {
2562
+ const tz = timezone ?? getBrowserTimezone();
2563
+ return startOfDayTs(date, tz) === startOfDayTs(getToday(tz), tz);
2537
2564
  }
2538
- function getToday() {
2539
- const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
2540
- const today = DateTz.now(timezone);
2541
- return today;
2565
+ function getToday(timezone) {
2566
+ return DateTz.now(timezone ?? getBrowserTimezone());
2542
2567
  }
2543
2568
 
2544
2569
  class DateTzPipe {
@@ -2560,6 +2585,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
2560
2585
  args: [{ name: 'dtz' }]
2561
2586
  }] });
2562
2587
 
2588
+ class DayOfWeekPipe {
2589
+ /**
2590
+ * @param value IDateTz
2591
+ * @param format 'long' (Friday), 'short' (Fri), 'narrow' (F)
2592
+ * @param locale Language, default = 'en-US'
2593
+ */
2594
+ transform(value, format = 'long', locale = 'en-US') {
2595
+ if (!value || typeof value.timestamp !== 'number') {
2596
+ return '';
2597
+ }
2598
+ let pattern = 'EEEE';
2599
+ if (format === 'short')
2600
+ pattern = 'EEE';
2601
+ if (format === 'narrow')
2602
+ pattern = 'EEEEE';
2603
+ try {
2604
+ return formatDate(value.timestamp, pattern, locale, value.timezone || undefined);
2605
+ }
2606
+ catch (error) {
2607
+ console.error('DayOfWeekPipe error:', error);
2608
+ return '';
2609
+ }
2610
+ }
2611
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: DayOfWeekPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
2612
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.15", ngImport: i0, type: DayOfWeekPipe, isStandalone: true, name: "dayOfWeek" }); }
2613
+ }
2614
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: DayOfWeekPipe, decorators: [{
2615
+ type: Pipe,
2616
+ args: [{ name: 'dayOfWeek' }]
2617
+ }] });
2618
+
2563
2619
  class CalendarEventComponent {
2564
2620
  constructor() {
2565
2621
  this.event = input.required(...(ngDevMode ? [{ debugName: "event" }] : /* istanbul ignore next */ []));
@@ -2622,43 +2678,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
2622
2678
  args: [{ selector: 'rlb-calendar-event', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgClass, DateTzPipe], template: "<div [ngClass]=\"classes()\" (click)=\"onClick($event)\">\n\n @if (!event().isOverflowIndicator) {\n <strong>{{ event().title }}</strong>\n <div class=\"small opacity-75\">\n {{ event().start | dtz:'HH:mm' }} - {{ event().end | dtz:'HH:mm' }}\n </div>\n }\n\n @if (event().isOverflowIndicator) {\n +{{ event().overlapCount }} more\n }\n</div>", styles: [":host{display:block;height:100%;overflow:hidden;border-radius:var(--bs-border-radius-sm);padding:0 1px;box-sizing:border-box;transition:box-shadow .2s}:host:hover{z-index:50;box-shadow:0 .5rem 1rem #00000026!important}.calendar-event{height:100%;width:100%;padding:2px 4px;font-size:.75rem;line-height:1.2;border-radius:var(--bs-border-radius-sm);cursor:pointer}.calendar-event.overflow-indicator{display:flex;align-items:center;justify-content:center;font-weight:600;border-style:dashed!important}.calendar-event.mode-week{height:100%;padding:2px 4px;font-size:.75rem;line-height:1.2}.calendar-event.mode-month{height:20px!important;padding:0 4px;line-height:20px;font-size:.75rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.calendar-event.mode-month.rounded-bottom-0{border-bottom-right-radius:0;border-bottom-left-radius:0}.calendar-event.mode-month.rounded-top-0{border-top-right-radius:0;border-top-left-radius:0}\n"] }]
2623
2679
  }], propDecorators: { event: [{ type: i0.Input, args: [{ isSignal: true, alias: "event", required: true }] }], view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: true }] }], eventClick: [{ type: i0.Output, args: ["event-click"] }], eventContainerClick: [{ type: i0.Output, args: ["event-container-click"] }] } });
2624
2680
 
2625
- class DayOfWeekPipe {
2626
- /**
2627
- * @param value IDateTz
2628
- * @param format 'long' (Friday), 'short' (Fri), 'narrow' (F)
2629
- * @param locale Language, default = 'en-US'
2630
- */
2631
- transform(value, format = 'long', locale = 'en-US') {
2632
- if (!value || typeof value.timestamp !== 'number') {
2633
- return '';
2634
- }
2635
- let pattern = 'EEEE';
2636
- if (format === 'short')
2637
- pattern = 'EEE';
2638
- if (format === 'narrow')
2639
- pattern = 'EEEEE';
2640
- try {
2641
- return formatDate(value.timestamp, pattern, locale, value.timezone || undefined);
2642
- }
2643
- catch (error) {
2644
- console.error('DayOfWeekPipe error:', error);
2645
- return '';
2646
- }
2647
- }
2648
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: DayOfWeekPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
2649
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.15", ngImport: i0, type: DayOfWeekPipe, isStandalone: true, name: "dayOfWeek" }); }
2650
- }
2651
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: DayOfWeekPipe, decorators: [{
2652
- type: Pipe,
2653
- args: [{ name: 'dayOfWeek' }]
2654
- }] });
2655
-
2656
2681
  class CalendarWeekGridComponent {
2657
2682
  constructor() {
2658
2683
  this.view = input.required(...(ngDevMode ? [{ debugName: "view" }] : /* istanbul ignore next */ []));
2659
2684
  this.currentDate = input.required(...(ngDevMode ? [{ debugName: "currentDate" }] : /* istanbul ignore next */ []));
2660
2685
  this.events = input([], ...(ngDevMode ? [{ debugName: "events" }] : /* istanbul ignore next */ []));
2661
2686
  this.intervals = input([], ...(ngDevMode ? [{ debugName: "intervals" }] : /* istanbul ignore next */ []));
2687
+ this.timezone = input.required(...(ngDevMode ? [{ debugName: "timezone" }] : /* istanbul ignore next */ []));
2662
2688
  this.layout = input.required(...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
2663
2689
  this.eventClick = output({ alias: 'event-click' });
2664
2690
  this.eventContainerClick = output({ alias: 'event-container-click' });
@@ -2686,6 +2712,10 @@ class CalendarWeekGridComponent {
2686
2712
  effect(() => {
2687
2713
  this.processAllEvents(this.events());
2688
2714
  });
2715
+ // Keep the "now" line in the calendar timezone.
2716
+ effect(() => {
2717
+ this.now.set(getToday(this.timezone()));
2718
+ });
2689
2719
  }
2690
2720
  ngAfterViewInit() {
2691
2721
  this.updateScrollbarWidth();
@@ -2721,13 +2751,12 @@ class CalendarWeekGridComponent {
2721
2751
  const rawMinutesFromStart = (newTopPx / this.layout().rowHeight) * 60;
2722
2752
  const snappedMinutes = Math.round(rawMinutesFromStart / this.SNAP_MINUTES) * this.SNAP_MINUTES;
2723
2753
  const validMinutes = Math.max(0, snappedMinutes);
2724
- const newStart = new DateTz$1(newDay)
2725
- .set(0, 'hour')
2726
- .set(0, 'minute')
2727
- .add(validMinutes, 'minute')
2728
- .stripSecMillis();
2754
+ // Local midnight of the target day + dropped offset (tz-aware).
2755
+ const tz = this.timezone();
2756
+ const newStartTs = startOfDayTs(newDay, tz) + validMinutes * 60 * 1000;
2757
+ const newStart = new DateTz$1(newStartTs, tz).stripSecMillis();
2729
2758
  const durationMs = movedEvent.end.timestamp - movedEvent.start.timestamp;
2730
- const newEnd = new DateTz$1(newStart.timestamp + durationMs).stripSecMillis();
2759
+ const newEnd = new DateTz$1(newStart.timestamp + durationMs, tz).stripSecMillis();
2731
2760
  if (newStart.timestamp !== movedEvent.start.timestamp) {
2732
2761
  const updatedEvent = {
2733
2762
  ...movedEvent,
@@ -2738,13 +2767,10 @@ class CalendarWeekGridComponent {
2738
2767
  }
2739
2768
  }
2740
2769
  getEventsForDay(day) {
2741
- const dayTs = new DateTz$1(day.timestamp, 'UTC').set(0, 'hour').set(0, 'minute').stripSecMillis().timestamp;
2742
- return this.processedEvents().get(dayTs) || [];
2770
+ return this.processedEvents().get(startOfDayTs(day, this.timezone())) || [];
2743
2771
  }
2744
2772
  calculateEventTop(event) {
2745
- const startOfDay = new DateTz$1(event.start).set(0, 'hour').set(0, 'minute').stripSecMillis();
2746
- const diffMs = event.start.timestamp - startOfDay.timestamp;
2747
- const diffMinutes = diffMs / (1000 * 60);
2773
+ const diffMinutes = minutesSinceMidnight(event.start, this.timezone());
2748
2774
  return (diffMinutes / 60) * this.layout().rowHeight;
2749
2775
  }
2750
2776
  calculateEventHeight(event) {
@@ -2759,13 +2785,13 @@ class CalendarWeekGridComponent {
2759
2785
  return ((hours * 60) + minutes) / 60 * this.layout().rowHeight;
2760
2786
  }
2761
2787
  isToday(date) {
2762
- return isToday(date);
2788
+ return isToday(date, this.timezone());
2763
2789
  }
2764
2790
  startNowTimer() {
2765
2791
  if (this.nowInterval)
2766
2792
  return;
2767
2793
  this.nowInterval = setInterval(() => {
2768
- this.now.set(getToday());
2794
+ this.now.set(getToday(this.timezone()));
2769
2795
  }, 60 * 1000); // every minute
2770
2796
  }
2771
2797
  stopNowTimer() {
@@ -2791,16 +2817,13 @@ class CalendarWeekGridComponent {
2791
2817
  return `var(--bs-${interval.color || 'success'})`;
2792
2818
  }
2793
2819
  buildWeekGrid(currentDate) {
2794
- const dayOfWeek = currentDate.dayOfWeek; // 0 = Sunday, 1 = Monday ...
2795
- // Week init (monday)
2796
- const start = new DateTz$1(currentDate.timestamp, 'UTC')
2797
- .add(-(dayOfWeek - 1), 'day') // clone or create new for start date
2798
- .set(0, 'hour')
2799
- .set(0, 'minute')
2800
- .stripSecMillis();
2820
+ const tz = this.timezone();
2821
+ const dayOfWeek = currentDate.cloneToTimezone(tz).dayOfWeek; // 0 = Sunday, 1 = Monday ...
2822
+ // Offset (in days) from currentDate back to the week's Monday.
2823
+ const mondayOffset = 1 - dayOfWeek; // Sun(0) -> +1, Mon(1) -> 0, Tue(2) -> -1 ...
2801
2824
  const newDays = [];
2802
2825
  for (let i = 0; i < 7; i++) {
2803
- newDays.push(new DateTz$1(start.timestamp, 'UTC').add(i, 'day'));
2826
+ newDays.push(dayAt(currentDate, tz, mondayOffset + i));
2804
2827
  }
2805
2828
  this.days.set(newDays);
2806
2829
  this.startNowTimer();
@@ -2821,37 +2844,32 @@ class CalendarWeekGridComponent {
2821
2844
  }
2822
2845
  processAllEvents(events) {
2823
2846
  const eventsByDay = new Map();
2847
+ const tz = this.timezone();
2824
2848
  for (const event of events) {
2825
- const originalStart = new DateTz$1(event.start).stripSecMillis();
2826
- const originalEnd = new DateTz$1(event.end).stripSecMillis();
2827
- let currentChunkStart = new DateTz$1(originalStart);
2828
- while (currentChunkStart.timestamp < originalEnd.timestamp) {
2829
- const startOfNextDay = new DateTz$1(currentChunkStart)
2830
- .set(0, 'hour')
2831
- .set(0, 'minute')
2832
- .add(1, 'day')
2833
- .stripSecMillis();
2834
- const chunkEndTimestamp = Math.min(originalEnd.timestamp, startOfNextDay.timestamp);
2835
- const chunkEnd = new DateTz$1(chunkEndTimestamp);
2836
- const currentDayStart = new DateTz$1(currentChunkStart)
2837
- .set(0, 'hour')
2838
- .set(0, 'minute')
2839
- .stripSecMillis();
2840
- const dayTimestamp = currentDayStart.timestamp;
2849
+ const originalStartTs = new DateTz$1(event.start).stripSecMillis().timestamp;
2850
+ const originalEndTs = new DateTz$1(event.end).stripSecMillis().timestamp;
2851
+ let chunkStartTs = originalStartTs;
2852
+ while (chunkStartTs < originalEndTs) {
2853
+ const chunkInst = new DateTz$1(chunkStartTs, tz);
2854
+ // tz-aware day boundaries (set()/add() would be UTC-naive here).
2855
+ const dayStartTs = startOfDayTs(chunkInst, tz);
2856
+ const startOfNextDayTs = dayAt(chunkInst, tz, 1).timestamp;
2857
+ const chunkEndTs = Math.min(originalEndTs, startOfNextDayTs);
2841
2858
  const visualEvent = {
2842
2859
  ...event,
2843
- start: currentChunkStart,
2844
- end: chunkEnd,
2845
- isContinuedBefore: currentChunkStart.timestamp > originalStart.timestamp,
2846
- isContinuedAfter: chunkEnd.timestamp < originalEnd.timestamp,
2860
+ // Chunks live in the calendar timezone, so labels and positions agree.
2861
+ start: new DateTz$1(chunkStartTs, tz),
2862
+ end: new DateTz$1(chunkEndTs, tz),
2863
+ isContinuedBefore: chunkStartTs > originalStartTs,
2864
+ isContinuedAfter: chunkEndTs < originalEndTs,
2847
2865
  left: 0,
2848
2866
  width: 0
2849
2867
  };
2850
- if (!eventsByDay.has(dayTimestamp)) {
2851
- eventsByDay.set(dayTimestamp, []);
2868
+ if (!eventsByDay.has(dayStartTs)) {
2869
+ eventsByDay.set(dayStartTs, []);
2852
2870
  }
2853
- eventsByDay.get(dayTimestamp).push(visualEvent);
2854
- currentChunkStart = startOfNextDay;
2871
+ eventsByDay.get(dayStartTs).push(visualEvent);
2872
+ chunkStartTs = startOfNextDayTs;
2855
2873
  }
2856
2874
  }
2857
2875
  const newProcessedEvents = new Map();
@@ -2957,8 +2975,8 @@ class CalendarWeekGridComponent {
2957
2975
  resultEvents.push({
2958
2976
  id: -9999,
2959
2977
  title: `+${hiddenEvents.length} more`,
2960
- start: new DateTz$1(minStart),
2961
- end: new DateTz$1(maxEnd),
2978
+ start: new DateTz$1(minStart, this.timezone()),
2979
+ end: new DateTz$1(maxEnd, this.timezone()),
2962
2980
  color: 'light',
2963
2981
  left: visibleColsCount * colWidth,
2964
2982
  width: colWidth,
@@ -2985,12 +3003,12 @@ class CalendarWeekGridComponent {
2985
3003
  });
2986
3004
  }
2987
3005
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: CalendarWeekGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2988
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: CalendarWeekGridComponent, isStandalone: true, selector: "rlb-calendar-week-grid", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: true, transformFunction: null }, currentDate: { classPropertyName: "currentDate", publicName: "currentDate", isSignal: true, isRequired: true, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, intervals: { classPropertyName: "intervals", publicName: "intervals", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { eventClick: "event-click", eventContainerClick: "event-container-click", eventChange: "event-change" }, viewQueries: [{ propertyName: "scrollBodyRef", first: true, predicate: ["scrollBody"], descendants: true, isSignal: true }, { propertyName: "headerRowRef", first: true, predicate: ["headerRow"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"calendar-wrapper d-flex flex-column\">\n\n <!-- HEADER WRAPPER -->\n <div #headerRow class=\"header-container overflow-hidden flex-shrink-0 border-bottom bg-body-tertiary\"\n [style.padding-right.px]=\"scrollbarWidth()\">\n\n <div class=\"header-row d-flex\" [style.min-height.rem]=\"layout().minHeaderHeight\">\n\n <div class=\"time-gutter border-end flex-shrink-0\"></div>\n\n <div class=\"days-header d-flex flex-grow-1\">\n @for (day of days(); track day.timestamp) {\n <div class=\"day-cell text-center p-2 border-end\" [class.text-primary]=\"isToday(day)\"\n [class.fw-bold]=\"isToday(day)\" [class.bg-primary]=\"isToday(day)\">\n <div class=\"small text-uppercase text-body-secondary\">{{ day | dayOfWeek: 'short' }}</div>\n <div class=\"h5 m-0\">{{ day | dtz:'DD' }}</div>\n </div>\n }\n </div>\n </div>\n </div>\n\n <!-- BODY WRAPPER -->\n <div #scrollBody class=\"calendar-body flex-grow-1 overflow-auto bg-body position-relative\"\n (scroll)=\"onBodyScroll($event)\" [style.max-height.rem]=\"layout().maxBodyHeight\">\n\n <div class=\"body-row d-flex position-relative\">\n\n <!-- SIDEBAR (Sticky Left) -->\n <div class=\"time-sidebar sticky-start flex-shrink-0 border-end\">\n @for (time of timeSlots(); track time; let i = $index) {\n <div class=\"time-slot-label small text-body-secondary d-flex align-items-start justify-content-center\"\n [style.height.px]=\"layout().rowHeight\">\n @if (i !== 0) {\n <span style=\"transform: translateY(-50%)\">\n {{ time }}\n </span>\n }\n </div>\n }\n </div>\n\n <!-- GRID AND EVENTS -->\n <div class=\"grid-layer flex-grow-1 position-relative\">\n\n <!-- LAYER 1: Grid -->\n <div class=\"background-grid position-absolute w-100 h-100 top-0 start-0 z-0\">\n @for (time of timeSlots(); track time) {\n <div class=\"grid-row border-bottom\" [style.height.px]=\"layout().rowHeight\">\n </div>\n }\n </div>\n\n <!-- Layer 1.5: Intervals (background highlights) -->\n <div class=\"intervals-container d-flex h-100 w-100 position-absolute top-0 start-0 z-0\" style=\"z-index: 0; pointer-events: none;\">\n @for (day of days(); track day.timestamp) {\n <div class=\"day-column position-relative border-end h-100\">\n @for (interval of getIntervalsForDay(day); track $index) {\n <div class=\"calendar-interval position-absolute w-100\"\n [style.top.px]=\"getIntervalTop(interval)\"\n [style.height.px]=\"getIntervalHeight(interval)\"\n [style.background-color]=\"getIntervalColor(interval)\">\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Layer 2: Events -->\n <div class=\"events-container d-flex h-100 w-100 position-relative z-1\" cdkDropListGroup>\n @for (day of days(); track day.timestamp) {\n <div class=\"day-column position-relative border-end h-100\" cdkDropList [cdkDropListSortingDisabled]=\"true\"\n [cdkDropListData]=\"day\" (cdkDropListDropped)=\"onEventDrop($event)\" (click)=\"eventClick.emit(undefined)\">\n @for (event of getEventsForDay(day); track trackByEventId($index, event)) {\n <rlb-calendar-event [view]=\"view()\" [event]=\"event\" [style.top.px]=\"calculateEventTop(event)\"\n [style.height.px]=\"calculateEventHeight(event)\" [style.left.%]=\"event.left\" [style.width.%]=\"event.width\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\" cdkDrag\n [cdkDragData]=\"event\" [cdkDragDisabled]=\"event.isOverflowIndicator\" class=\"position-absolute\">\n <div *cdkDragPlaceholder style=\"opacity: 0\"></div>\n </rlb-calendar-event>\n }\n @if (isToday(day)) {\n <div class=\"now-line\" [style.top.px]=\"getNowTop()\">\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [":host{display:block;height:100%}.calendar-wrapper{background-color:var(--bs-body-bg);border:1px solid var(--bs-border-color);border-radius:var(--bs-border-radius);overflow:hidden;height:100%}.header-container{background-color:var(--bs-body-bg);z-index:102;box-shadow:0 4px 6px -4px #0000001a}.header-row{width:fit-content;min-width:100%}.time-gutter{width:60px;border-color:var(--bs-border-color)!important}.day-cell{border-color:var(--bs-border-color)!important;flex:1 1 0px;width:0;min-width:120px;overflow:hidden}.day-cell:last-child{border-right:none!important}.calendar-body{scroll-behavior:auto}.body-row{width:fit-content;min-width:100%}.sticky-start{position:sticky;left:0;z-index:50;background-color:var(--bs-body-bg)}.time-sidebar{width:60px;border-color:var(--bs-border-color)!important}.grid-row{border-color:var(--bs-border-color)!important;box-sizing:border-box}.grid-row:after{content:\"\";position:absolute;width:100%;border-bottom:1px dotted currentColor;opacity:.15;top:50%;left:0;pointer-events:none}.day-column{border-color:var(--bs-border-color)!important;flex:1 1 0px;width:0;min-width:120px}.day-column:last-child{border-right:none!important}.now-line{position:absolute;left:0;right:0;height:2px;background-color:var(--bs-danger);z-index:10;pointer-events:none}.now-line:before{content:\"\";position:absolute;left:-5px;top:-4px;width:10px;height:10px;background-color:var(--bs-danger);border-radius:50%}.calendar-interval{opacity:.1;pointer-events:none;border-radius:0}.intervals-container .day-column{flex:1 1 0px;width:0;min-width:120px}.intervals-container .day-column:last-child{border-right:none!important}.z-0{z-index:0}.z-1{z-index:1}\n"], dependencies: [{ kind: "directive", type: CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "component", type: CalendarEventComponent, selector: "rlb-calendar-event", inputs: ["event", "view"], outputs: ["event-click", "event-container-click"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "pipe", type: DateTzPipe, name: "dtz" }, { kind: "pipe", type: DayOfWeekPipe, name: "dayOfWeek" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3006
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: CalendarWeekGridComponent, isStandalone: true, selector: "rlb-calendar-week-grid", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: true, transformFunction: null }, currentDate: { classPropertyName: "currentDate", publicName: "currentDate", isSignal: true, isRequired: true, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, intervals: { classPropertyName: "intervals", publicName: "intervals", isSignal: true, isRequired: false, transformFunction: null }, timezone: { classPropertyName: "timezone", publicName: "timezone", isSignal: true, isRequired: true, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { eventClick: "event-click", eventContainerClick: "event-container-click", eventChange: "event-change" }, viewQueries: [{ propertyName: "scrollBodyRef", first: true, predicate: ["scrollBody"], descendants: true, isSignal: true }, { propertyName: "headerRowRef", first: true, predicate: ["headerRow"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"calendar-wrapper d-flex flex-column\">\n\n <!-- HEADER WRAPPER -->\n <div #headerRow class=\"header-container overflow-hidden flex-shrink-0 border-bottom bg-body-tertiary\"\n [style.padding-right.px]=\"scrollbarWidth()\">\n\n <div class=\"header-row d-flex\" [style.min-height.rem]=\"layout().minHeaderHeight\">\n\n <div class=\"time-gutter border-end flex-shrink-0\"></div>\n\n <div class=\"days-header d-flex flex-grow-1\">\n @for (day of days(); track day.timestamp) {\n <div class=\"day-cell text-center p-2 border-end\" [class.text-primary]=\"isToday(day)\"\n [class.fw-bold]=\"isToday(day)\" [class.bg-primary]=\"isToday(day)\">\n <div class=\"small text-uppercase text-body-secondary\">{{ day | dayOfWeek: 'short' }}</div>\n <div class=\"h5 m-0\">{{ day | dtz:'DD' }}</div>\n </div>\n }\n </div>\n </div>\n </div>\n\n <!-- BODY WRAPPER -->\n <div #scrollBody class=\"calendar-body flex-grow-1 overflow-auto bg-body position-relative\"\n (scroll)=\"onBodyScroll($event)\" [style.max-height.rem]=\"layout().maxBodyHeight\">\n\n <div class=\"body-row d-flex position-relative\">\n\n <!-- SIDEBAR (Sticky Left) -->\n <div class=\"time-sidebar sticky-start flex-shrink-0 border-end\">\n @for (time of timeSlots(); track time; let i = $index) {\n <div class=\"time-slot-label small text-body-secondary d-flex align-items-start justify-content-center\"\n [style.height.px]=\"layout().rowHeight\">\n @if (i !== 0) {\n <span style=\"transform: translateY(-50%)\">\n {{ time }}\n </span>\n }\n </div>\n }\n </div>\n\n <!-- GRID AND EVENTS -->\n <div class=\"grid-layer flex-grow-1 position-relative\">\n\n <!-- LAYER 1: Grid -->\n <div class=\"background-grid position-absolute w-100 h-100 top-0 start-0 z-0\">\n @for (time of timeSlots(); track time) {\n <div class=\"grid-row border-bottom\" [style.height.px]=\"layout().rowHeight\">\n </div>\n }\n </div>\n\n <!-- Layer 1.5: Intervals (background highlights) -->\n <div class=\"intervals-container d-flex h-100 w-100 position-absolute top-0 start-0 z-0\" style=\"z-index: 0; pointer-events: none;\">\n @for (day of days(); track day.timestamp) {\n <div class=\"day-column position-relative border-end h-100\">\n @for (interval of getIntervalsForDay(day); track $index) {\n <div class=\"calendar-interval position-absolute w-100\"\n [style.top.px]=\"getIntervalTop(interval)\"\n [style.height.px]=\"getIntervalHeight(interval)\"\n [style.background-color]=\"getIntervalColor(interval)\">\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Layer 2: Events -->\n <div class=\"events-container d-flex h-100 w-100 position-relative z-1\" cdkDropListGroup>\n @for (day of days(); track day.timestamp) {\n <div class=\"day-column position-relative border-end h-100\" cdkDropList [cdkDropListSortingDisabled]=\"true\"\n [cdkDropListData]=\"day\" (cdkDropListDropped)=\"onEventDrop($event)\" (click)=\"eventClick.emit(undefined)\">\n @for (event of getEventsForDay(day); track trackByEventId($index, event)) {\n <rlb-calendar-event [view]=\"view()\" [event]=\"event\" [style.top.px]=\"calculateEventTop(event)\"\n [style.height.px]=\"calculateEventHeight(event)\" [style.left.%]=\"event.left\" [style.width.%]=\"event.width\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\" cdkDrag\n [cdkDragData]=\"event\" [cdkDragDisabled]=\"event.isOverflowIndicator\" class=\"position-absolute\">\n <div *cdkDragPlaceholder style=\"opacity: 0\"></div>\n </rlb-calendar-event>\n }\n @if (isToday(day)) {\n <div class=\"now-line\" [style.top.px]=\"getNowTop()\">\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [":host{display:block;height:100%}.calendar-wrapper{background-color:var(--bs-body-bg);border:1px solid var(--bs-border-color);border-radius:var(--bs-border-radius);overflow:hidden;height:100%}.header-container{background-color:var(--bs-body-bg);z-index:102;box-shadow:0 4px 6px -4px #0000001a}.header-row{width:fit-content;min-width:100%}.time-gutter{width:60px;border-color:var(--bs-border-color)!important}.day-cell{border-color:var(--bs-border-color)!important;flex:1 1 0px;width:0;min-width:120px;overflow:hidden}.day-cell:last-child{border-right:none!important}.calendar-body{scroll-behavior:auto}.body-row{width:fit-content;min-width:100%}.sticky-start{position:sticky;left:0;z-index:50;background-color:var(--bs-body-bg)}.time-sidebar{width:60px;border-color:var(--bs-border-color)!important}.grid-row{border-color:var(--bs-border-color)!important;box-sizing:border-box}.grid-row:after{content:\"\";position:absolute;width:100%;border-bottom:1px dotted currentColor;opacity:.15;top:50%;left:0;pointer-events:none}.day-column{border-color:var(--bs-border-color)!important;flex:1 1 0px;width:0;min-width:120px}.day-column:last-child{border-right:none!important}.now-line{position:absolute;left:0;right:0;height:2px;background-color:var(--bs-danger);z-index:10;pointer-events:none}.now-line:before{content:\"\";position:absolute;left:-5px;top:-4px;width:10px;height:10px;background-color:var(--bs-danger);border-radius:50%}.calendar-interval{opacity:.1;pointer-events:none;border-radius:0}.intervals-container .day-column{flex:1 1 0px;width:0;min-width:120px}.intervals-container .day-column:last-child{border-right:none!important}.z-0{z-index:0}.z-1{z-index:1}\n"], dependencies: [{ kind: "directive", type: CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "component", type: CalendarEventComponent, selector: "rlb-calendar-event", inputs: ["event", "view"], outputs: ["event-click", "event-container-click"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "pipe", type: DateTzPipe, name: "dtz" }, { kind: "pipe", type: DayOfWeekPipe, name: "dayOfWeek" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2989
3007
  }
2990
3008
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: CalendarWeekGridComponent, decorators: [{
2991
3009
  type: Component,
2992
3010
  args: [{ selector: 'rlb-calendar-week-grid', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CdkDropListGroup, CdkDropList, CalendarEventComponent, CdkDrag, CdkDragPlaceholder, DateTzPipe, DayOfWeekPipe], template: "<div class=\"calendar-wrapper d-flex flex-column\">\n\n <!-- HEADER WRAPPER -->\n <div #headerRow class=\"header-container overflow-hidden flex-shrink-0 border-bottom bg-body-tertiary\"\n [style.padding-right.px]=\"scrollbarWidth()\">\n\n <div class=\"header-row d-flex\" [style.min-height.rem]=\"layout().minHeaderHeight\">\n\n <div class=\"time-gutter border-end flex-shrink-0\"></div>\n\n <div class=\"days-header d-flex flex-grow-1\">\n @for (day of days(); track day.timestamp) {\n <div class=\"day-cell text-center p-2 border-end\" [class.text-primary]=\"isToday(day)\"\n [class.fw-bold]=\"isToday(day)\" [class.bg-primary]=\"isToday(day)\">\n <div class=\"small text-uppercase text-body-secondary\">{{ day | dayOfWeek: 'short' }}</div>\n <div class=\"h5 m-0\">{{ day | dtz:'DD' }}</div>\n </div>\n }\n </div>\n </div>\n </div>\n\n <!-- BODY WRAPPER -->\n <div #scrollBody class=\"calendar-body flex-grow-1 overflow-auto bg-body position-relative\"\n (scroll)=\"onBodyScroll($event)\" [style.max-height.rem]=\"layout().maxBodyHeight\">\n\n <div class=\"body-row d-flex position-relative\">\n\n <!-- SIDEBAR (Sticky Left) -->\n <div class=\"time-sidebar sticky-start flex-shrink-0 border-end\">\n @for (time of timeSlots(); track time; let i = $index) {\n <div class=\"time-slot-label small text-body-secondary d-flex align-items-start justify-content-center\"\n [style.height.px]=\"layout().rowHeight\">\n @if (i !== 0) {\n <span style=\"transform: translateY(-50%)\">\n {{ time }}\n </span>\n }\n </div>\n }\n </div>\n\n <!-- GRID AND EVENTS -->\n <div class=\"grid-layer flex-grow-1 position-relative\">\n\n <!-- LAYER 1: Grid -->\n <div class=\"background-grid position-absolute w-100 h-100 top-0 start-0 z-0\">\n @for (time of timeSlots(); track time) {\n <div class=\"grid-row border-bottom\" [style.height.px]=\"layout().rowHeight\">\n </div>\n }\n </div>\n\n <!-- Layer 1.5: Intervals (background highlights) -->\n <div class=\"intervals-container d-flex h-100 w-100 position-absolute top-0 start-0 z-0\" style=\"z-index: 0; pointer-events: none;\">\n @for (day of days(); track day.timestamp) {\n <div class=\"day-column position-relative border-end h-100\">\n @for (interval of getIntervalsForDay(day); track $index) {\n <div class=\"calendar-interval position-absolute w-100\"\n [style.top.px]=\"getIntervalTop(interval)\"\n [style.height.px]=\"getIntervalHeight(interval)\"\n [style.background-color]=\"getIntervalColor(interval)\">\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Layer 2: Events -->\n <div class=\"events-container d-flex h-100 w-100 position-relative z-1\" cdkDropListGroup>\n @for (day of days(); track day.timestamp) {\n <div class=\"day-column position-relative border-end h-100\" cdkDropList [cdkDropListSortingDisabled]=\"true\"\n [cdkDropListData]=\"day\" (cdkDropListDropped)=\"onEventDrop($event)\" (click)=\"eventClick.emit(undefined)\">\n @for (event of getEventsForDay(day); track trackByEventId($index, event)) {\n <rlb-calendar-event [view]=\"view()\" [event]=\"event\" [style.top.px]=\"calculateEventTop(event)\"\n [style.height.px]=\"calculateEventHeight(event)\" [style.left.%]=\"event.left\" [style.width.%]=\"event.width\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\" cdkDrag\n [cdkDragData]=\"event\" [cdkDragDisabled]=\"event.isOverflowIndicator\" class=\"position-absolute\">\n <div *cdkDragPlaceholder style=\"opacity: 0\"></div>\n </rlb-calendar-event>\n }\n @if (isToday(day)) {\n <div class=\"now-line\" [style.top.px]=\"getNowTop()\">\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [":host{display:block;height:100%}.calendar-wrapper{background-color:var(--bs-body-bg);border:1px solid var(--bs-border-color);border-radius:var(--bs-border-radius);overflow:hidden;height:100%}.header-container{background-color:var(--bs-body-bg);z-index:102;box-shadow:0 4px 6px -4px #0000001a}.header-row{width:fit-content;min-width:100%}.time-gutter{width:60px;border-color:var(--bs-border-color)!important}.day-cell{border-color:var(--bs-border-color)!important;flex:1 1 0px;width:0;min-width:120px;overflow:hidden}.day-cell:last-child{border-right:none!important}.calendar-body{scroll-behavior:auto}.body-row{width:fit-content;min-width:100%}.sticky-start{position:sticky;left:0;z-index:50;background-color:var(--bs-body-bg)}.time-sidebar{width:60px;border-color:var(--bs-border-color)!important}.grid-row{border-color:var(--bs-border-color)!important;box-sizing:border-box}.grid-row:after{content:\"\";position:absolute;width:100%;border-bottom:1px dotted currentColor;opacity:.15;top:50%;left:0;pointer-events:none}.day-column{border-color:var(--bs-border-color)!important;flex:1 1 0px;width:0;min-width:120px}.day-column:last-child{border-right:none!important}.now-line{position:absolute;left:0;right:0;height:2px;background-color:var(--bs-danger);z-index:10;pointer-events:none}.now-line:before{content:\"\";position:absolute;left:-5px;top:-4px;width:10px;height:10px;background-color:var(--bs-danger);border-radius:50%}.calendar-interval{opacity:.1;pointer-events:none;border-radius:0}.intervals-container .day-column{flex:1 1 0px;width:0;min-width:120px}.intervals-container .day-column:last-child{border-right:none!important}.z-0{z-index:0}.z-1{z-index:1}\n"] }]
2993
- }], ctorParameters: () => [], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: true }] }], currentDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentDate", required: true }] }], events: [{ type: i0.Input, args: [{ isSignal: true, alias: "events", required: false }] }], intervals: [{ type: i0.Input, args: [{ isSignal: true, alias: "intervals", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }], eventClick: [{ type: i0.Output, args: ["event-click"] }], eventContainerClick: [{ type: i0.Output, args: ["event-container-click"] }], eventChange: [{ type: i0.Output, args: ["event-change"] }], scrollBodyRef: [{ type: i0.ViewChild, args: ['scrollBody', { isSignal: true }] }], headerRowRef: [{ type: i0.ViewChild, args: ['headerRow', { isSignal: true }] }] } });
3011
+ }], ctorParameters: () => [], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: true }] }], currentDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentDate", required: true }] }], events: [{ type: i0.Input, args: [{ isSignal: true, alias: "events", required: false }] }], intervals: [{ type: i0.Input, args: [{ isSignal: true, alias: "intervals", required: false }] }], timezone: [{ type: i0.Input, args: [{ isSignal: true, alias: "timezone", required: true }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }], eventClick: [{ type: i0.Output, args: ["event-click"] }], eventContainerClick: [{ type: i0.Output, args: ["event-container-click"] }], eventChange: [{ type: i0.Output, args: ["event-change"] }], scrollBodyRef: [{ type: i0.ViewChild, args: ['scrollBody', { isSignal: true }] }], headerRowRef: [{ type: i0.ViewChild, args: ['headerRow', { isSignal: true }] }] } });
2994
3012
 
2995
3013
  const MAX_EVENTS_PER_CELL = 3;
2996
3014
  const DAYS_IN_GRID = 42; // 6 weeks * 7 days
@@ -3000,6 +3018,7 @@ class CalendarMonthGridComponent {
3000
3018
  this.currentDate = input.required(...(ngDevMode ? [{ debugName: "currentDate" }] : /* istanbul ignore next */ []));
3001
3019
  this.events = input([], ...(ngDevMode ? [{ debugName: "events" }] : /* istanbul ignore next */ []));
3002
3020
  this.intervals = input([], ...(ngDevMode ? [{ debugName: "intervals" }] : /* istanbul ignore next */ []));
3021
+ this.timezone = input.required(...(ngDevMode ? [{ debugName: "timezone" }] : /* istanbul ignore next */ []));
3003
3022
  this.layout = input.required(...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
3004
3023
  this.eventClick = output({ alias: 'event-click' });
3005
3024
  this.eventContainerClick = output({ alias: 'event-container-click' });
@@ -3043,7 +3062,7 @@ class CalendarMonthGridComponent {
3043
3062
  }
3044
3063
  // --- Helpers ---
3045
3064
  isToday(date) {
3046
- return isToday(date);
3065
+ return isToday(date, this.timezone());
3047
3066
  }
3048
3067
  hasInterval(date) {
3049
3068
  const dayOfWeek = new DateTz(date).dayOfWeek;
@@ -3066,21 +3085,18 @@ class CalendarMonthGridComponent {
3066
3085
  }
3067
3086
  // --- Core Logic ---
3068
3087
  buildMonthGrid() {
3069
- // 1. Calculate Grid Boundaries
3070
- const current = new DateTz(this.currentDate());
3071
- // Find the first day of the month
3072
- const startOfMonth = new DateTz(current).set(1, 'day').set(0, 'hour').set(0, 'minute').stripSecMillis();
3073
- // Calculate offset to find the start of the grid (e.g. Monday)
3074
- const dayOfWeek = startOfMonth.dayOfWeek; // 0 = Sun, 1 = Mon...
3075
- // Adjust logic based on your locale start of week (assuming Monday start here)
3088
+ const tz = this.timezone();
3089
+ // 1. Calculate Grid Boundaries (tz-aware; set()/add() would be UTC-naive)
3090
+ const current = this.currentDate().cloneToTimezone(tz);
3091
+ // First day of the month at local midnight
3092
+ const firstOfMonth = dayAt(current, tz, -(current.day - 1));
3093
+ // Calculate offset to find the start of the grid (Monday-first)
3094
+ const dayOfWeek = firstOfMonth.dayOfWeek; // 0 = Sun, 1 = Mon...
3076
3095
  const offset = dayOfWeek === 0 ? 6 : dayOfWeek - 1;
3077
- const gridStart = new DateTz(startOfMonth).add(-offset, 'day');
3078
3096
  // 2. Generate Days
3079
3097
  const days = [];
3080
- let iter = new DateTz(gridStart);
3081
3098
  for (let i = 0; i < DAYS_IN_GRID; i++) {
3082
- days.push(iter);
3083
- iter = new DateTz(iter).add(1, 'day');
3099
+ days.push(dayAt(firstOfMonth, tz, i - offset));
3084
3100
  }
3085
3101
  // Header is just the first week
3086
3102
  this.weekDaysHeader.set(days.slice(0, 7));
@@ -3135,6 +3151,7 @@ class CalendarMonthGridComponent {
3135
3151
  * Places events into rows so that long events maintain their vertical position across days.
3136
3152
  */
3137
3153
  calculateEventSlots(days, events) {
3154
+ const tz = this.timezone();
3138
3155
  const dayMap = new Map();
3139
3156
  days.forEach(d => dayMap.set(d.timestamp, []));
3140
3157
  // Sort: Longest events first, then by start time
@@ -3148,25 +3165,18 @@ class CalendarMonthGridComponent {
3148
3165
  const gridStartTs = days[0].timestamp;
3149
3166
  const lastDay = days[days.length - 1];
3150
3167
  // End of grid is the start of the next day after the last cell
3151
- const gridEndTs = new DateTz(lastDay).add(1, 'day').timestamp;
3168
+ const gridEndTs = dayAt(lastDay, tz, 1).timestamp;
3152
3169
  for (const event of sortedEvents) {
3153
- // Normalize start to beginning of day
3154
- const evtStart = new DateTz(event.start).set(0, 'hour').set(0, 'minute').stripSecMillis();
3155
- const evtEndRaw = new DateTz(event.end).stripSecMillis();
3156
- // Normalize end.
3157
- // If ends at 00:00, it effectively ends at the previous day visually.
3158
- // Else, round up to the end of that day.
3159
- let evtEnd;
3160
- const isMidnight = evtEndRaw.hour === 0 && evtEndRaw.minute === 0;
3161
- if (evtEndRaw.timestamp > evtStart.timestamp && isMidnight) {
3162
- evtEnd = evtEndRaw; // Keeps it clean for comparison, effectively 00:00 of next day
3163
- }
3164
- else {
3165
- // Round to start of next day to cover full day
3166
- evtEnd = new DateTz(evtEndRaw).set(0, 'hour').set(0, 'minute').add(1, 'day').stripSecMillis();
3167
- }
3170
+ // tz-aware day-floors (set()/add() would be UTC-naive).
3171
+ const evtStartTs = startOfDayTs(event.start, tz);
3172
+ // Normalize end. If it ends exactly at local 00:00, it visually ends on the
3173
+ // previous day; otherwise round up to the start of the next day.
3174
+ const endsAtMidnight = minutesSinceMidnight(event.end, tz) === 0;
3175
+ const evtEndTs = (event.end.timestamp > evtStartTs && endsAtMidnight)
3176
+ ? startOfDayTs(event.end, tz)
3177
+ : dayAt(event.end, tz, 1).timestamp;
3168
3178
  // Skip if completely outside grid
3169
- if (evtEnd.timestamp <= gridStartTs || evtStart.timestamp >= gridEndTs) {
3179
+ if (evtEndTs <= gridStartTs || evtStartTs >= gridEndTs) {
3170
3180
  continue;
3171
3181
  }
3172
3182
  // Find which grid indices this event occupies
@@ -3174,7 +3184,7 @@ class CalendarMonthGridComponent {
3174
3184
  for (let i = 0; i < days.length; i++) {
3175
3185
  const dTs = days[i].timestamp;
3176
3186
  // Check intersection: [DayStart, DayEnd) overlaps [EventStart, EventEnd)
3177
- if (dTs >= evtStart.timestamp && dTs < evtEnd.timestamp) {
3187
+ if (dTs >= evtStartTs && dTs < evtEndTs) {
3178
3188
  daysIndices.push(i);
3179
3189
  }
3180
3190
  }
@@ -3211,15 +3221,17 @@ class CalendarMonthGridComponent {
3211
3221
  }
3212
3222
  const isFirstRenderDay = (i === 0);
3213
3223
  const isLastRenderDay = (i === daysIndices.length - 1);
3224
+ // `dayInTz` is the grid cell, already in the calendar timezone.
3225
+ const dayInTz = days[idx];
3226
+ const currentDayEnd = dayAt(dayInTz, tz, 1);
3214
3227
  // Visual flags for rounding corners
3215
- const isContinuedBefore = !isFirstRenderDay || (evtStart.timestamp < days[daysIndices[0]].timestamp);
3216
- const currentDayEndTs = new DateTz(dTs).add(1, 'day').timestamp;
3217
- const isContinuedAfter = !isLastRenderDay || (evtEnd.timestamp > currentDayEndTs);
3228
+ const isContinuedBefore = !isFirstRenderDay || (evtStartTs < days[daysIndices[0]].timestamp);
3229
+ const isContinuedAfter = !isLastRenderDay || (evtEndTs > currentDayEnd.timestamp);
3218
3230
  const eventView = {
3219
3231
  ...event,
3220
3232
  // Override start/end for the specific cell (crucial for DnD to know the cell context)
3221
- start: new DateTz(dTs),
3222
- end: new DateTz(currentDayEndTs),
3233
+ start: new DateTz(dayInTz),
3234
+ end: new DateTz(currentDayEnd),
3223
3235
  originalStart: event.start,
3224
3236
  originalEnd: event.end,
3225
3237
  isContinuedBefore,
@@ -3255,12 +3267,12 @@ class CalendarMonthGridComponent {
3255
3267
  this.eventChange.emit(updatedEvent);
3256
3268
  }
3257
3269
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: CalendarMonthGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3258
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: CalendarMonthGridComponent, isStandalone: true, selector: "rlb-calendar-month-grid", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: true, transformFunction: null }, currentDate: { classPropertyName: "currentDate", publicName: "currentDate", isSignal: true, isRequired: true, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, intervals: { classPropertyName: "intervals", publicName: "intervals", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { eventClick: "event-click", eventContainerClick: "event-container-click", eventChange: "event-change" }, viewQueries: [{ propertyName: "scrollBodyRef", first: true, predicate: ["scrollBody"], descendants: true, isSignal: true }, { propertyName: "headerRowRef", first: true, predicate: ["headerRow"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"d-flex flex-column w-100 bg-body user-select-none month-view-root\">\n <!-- 1. Header Row (Fixed) -->\n <div #headerRow class=\"d-flex flex-shrink-0 border-bottom bg-body-tertiary overflow-hidden\"\n [style.min-height.rem]=\"layout().minHeaderHeight\" [style.padding-right.px]=\"scrollbarWidth()\">\n @for (day of weekDaysHeader(); track day) {\n <div class=\"flex-fill text-center py-2 border-end fw-bold text-secondary text-uppercase w-0 my-auto h6\">\n {{ day | dayOfWeek:'short' }}\n </div>\n }\n </div>\n\n <!-- SCROLL CONTAINER -->\n <div #scrollBody class=\"calendar-scroller flex-grow-1 overflow-auto bg-body position-relative\"\n [style.max-height.rem]=\"layout().maxBodyHeight\" (scroll)=\"onBodyScroll($event)\">\n\n <!-- 2. Grid Body (Scrollable) -->\n <div class=\"d-flex flex-column flex-grow-1 border-start min-height-0\">\n\n <div class=\"d-flex flex-column\" cdkDropListGroup>\n @for (week of weeks(); track week) {\n <div class=\"d-flex border-bottom min-h-row\" style=\"flex: 1 0 auto;\" [style.min-height.px]=\"layout().rowHeight\">\n @for (slot of week; track slot) {\n <div class=\"flex-fill border-end p-1 d-flex flex-column position-relative\" style=\"width: 0\"\n [class.bg-light]=\"!isCurrentMonth(slot.date)\"\n [class.has-interval]=\"hasInterval(slot.date)\"\n [style.--interval-color]=\"getIntervalColor(slot.date)\"\n cdkDropList [cdkDropListData]=\"slot.date\"\n (cdkDropListDropped)=\"onEventDrop($event)\" (click)=\"eventClick.emit(undefined)\">\n <!-- Date Number -->\n <div class=\"d-flex justify-content-center mb-1\">\n <span class=\"day-number d-flex align-items-center justify-content-center\"\n [class.today]=\"isToday(slot.date)\">\n {{ slot.date | dtz:'DD' }}\n </span>\n </div>\n <!-- Events Stack -->\n <div class=\"d-flex flex-column gap-1 w-100\">\n @for (event of slot.events; track trackByEvent($index, event)) {\n <!-- Spacer -->\n @if (event.isSpacer) {\n <div class=\"event-spacer\"></div>\n }\n <!-- Event -->\n @if (!event.isSpacer) {\n <rlb-calendar-event [event]=\"event\" class=\"w-100\" cdkDrag [cdkDragData]=\"event\"\n (event-click)=\"eventClick.emit($event)\" [view]=\"view()\">\n <!-- Drag Preview (Optional but nice) -->\n <div *cdkDragPlaceholder style=\"opacity: 0\"></div>\n <ng-template cdkDragPreview matchSize class=\"rlb-calendar-drag-preview\">\n <rlb-calendar-event [event]=\"event\" [view]=\"view()\" style=\"box-sizing: border-box;\">\n </rlb-calendar-event>\n </ng-template>\n </rlb-calendar-event>\n }\n }\n </div>\n <!-- Overflow (+N more) -->\n @if (slot.hasOverflow) {\n <div class=\"mt-1 small text-secondary text-center cursor-pointer p-1 rounded hover-bg\"\n (click)=\"$event.stopPropagation(); eventContainerClick.emit(slot.overflowEvents)\">\n +{{ slot.overflowCount }} more\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n </div>\n</div>\n", styles: [":host{display:block;height:100%}.min-height-0{min-height:0!important}.border-end:last-child{border-right:0!important}.day-number{width:24px;height:24px;border-radius:50%;font-size:.85rem;font-weight:500;transition:background-color .2s}.day-number.today{background-color:var(--bs-primary);color:#fff}.event-spacer{height:20px;width:100%;pointer-events:none}.hover-bg:hover{background-color:var(--bs-secondary-bg-subtle)}.cursor-pointer{cursor:pointer}.has-interval{background-image:linear-gradient(to right,color-mix(in srgb,var(--interval-color) 12%,transparent) 0%,transparent 100%);border-left:3px solid var(--interval-color)!important}.cdk-drag-preview{box-shadow:0 .5rem 1rem #0000004d;border-radius:var(--bs-border-radius-sm)}\n"], dependencies: [{ kind: "directive", type: CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "component", type: CalendarEventComponent, selector: "rlb-calendar-event", inputs: ["event", "view"], outputs: ["event-click", "event-container-click"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "directive", type: CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "pipe", type: DateTzPipe, name: "dtz" }, { kind: "pipe", type: DayOfWeekPipe, name: "dayOfWeek" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3270
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: CalendarMonthGridComponent, isStandalone: true, selector: "rlb-calendar-month-grid", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: true, transformFunction: null }, currentDate: { classPropertyName: "currentDate", publicName: "currentDate", isSignal: true, isRequired: true, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, intervals: { classPropertyName: "intervals", publicName: "intervals", isSignal: true, isRequired: false, transformFunction: null }, timezone: { classPropertyName: "timezone", publicName: "timezone", isSignal: true, isRequired: true, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { eventClick: "event-click", eventContainerClick: "event-container-click", eventChange: "event-change" }, viewQueries: [{ propertyName: "scrollBodyRef", first: true, predicate: ["scrollBody"], descendants: true, isSignal: true }, { propertyName: "headerRowRef", first: true, predicate: ["headerRow"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"d-flex flex-column w-100 bg-body user-select-none month-view-root\">\n <!-- 1. Header Row (Fixed) -->\n <div #headerRow class=\"d-flex flex-shrink-0 border-bottom bg-body-tertiary overflow-hidden\"\n [style.min-height.rem]=\"layout().minHeaderHeight\" [style.padding-right.px]=\"scrollbarWidth()\">\n @for (day of weekDaysHeader(); track day) {\n <div class=\"flex-fill text-center py-2 border-end fw-bold text-secondary text-uppercase w-0 my-auto h6\">\n {{ day | dayOfWeek:'short' }}\n </div>\n }\n </div>\n\n <!-- SCROLL CONTAINER -->\n <div #scrollBody class=\"calendar-scroller flex-grow-1 overflow-auto bg-body position-relative\"\n [style.max-height.rem]=\"layout().maxBodyHeight\" (scroll)=\"onBodyScroll($event)\">\n\n <!-- 2. Grid Body (Scrollable) -->\n <div class=\"d-flex flex-column flex-grow-1 border-start min-height-0\">\n\n <div class=\"d-flex flex-column\" cdkDropListGroup>\n @for (week of weeks(); track week) {\n <div class=\"d-flex border-bottom min-h-row\" style=\"flex: 1 0 auto;\" [style.min-height.px]=\"layout().rowHeight\">\n @for (slot of week; track slot) {\n <div class=\"flex-fill border-end p-1 d-flex flex-column position-relative\" style=\"width: 0\"\n [class.bg-light]=\"!isCurrentMonth(slot.date)\"\n [class.has-interval]=\"hasInterval(slot.date)\"\n [style.--interval-color]=\"getIntervalColor(slot.date)\"\n cdkDropList [cdkDropListData]=\"slot.date\"\n (cdkDropListDropped)=\"onEventDrop($event)\" (click)=\"eventClick.emit(undefined)\">\n <!-- Date Number -->\n <div class=\"d-flex justify-content-center mb-1\">\n <span class=\"day-number d-flex align-items-center justify-content-center\"\n [class.today]=\"isToday(slot.date)\">\n {{ slot.date | dtz:'DD' }}\n </span>\n </div>\n <!-- Events Stack -->\n <div class=\"d-flex flex-column gap-1 w-100\">\n @for (event of slot.events; track trackByEvent($index, event)) {\n <!-- Spacer -->\n @if (event.isSpacer) {\n <div class=\"event-spacer\"></div>\n }\n <!-- Event -->\n @if (!event.isSpacer) {\n <rlb-calendar-event [event]=\"event\" class=\"w-100\" cdkDrag [cdkDragData]=\"event\"\n (event-click)=\"eventClick.emit($event)\" [view]=\"view()\">\n <!-- Drag Preview (Optional but nice) -->\n <div *cdkDragPlaceholder style=\"opacity: 0\"></div>\n <ng-template cdkDragPreview matchSize class=\"rlb-calendar-drag-preview\">\n <rlb-calendar-event [event]=\"event\" [view]=\"view()\" style=\"box-sizing: border-box;\">\n </rlb-calendar-event>\n </ng-template>\n </rlb-calendar-event>\n }\n }\n </div>\n <!-- Overflow (+N more) -->\n @if (slot.hasOverflow) {\n <div class=\"mt-1 small text-secondary text-center cursor-pointer p-1 rounded hover-bg\"\n (click)=\"$event.stopPropagation(); eventContainerClick.emit(slot.overflowEvents)\">\n +{{ slot.overflowCount }} more\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n </div>\n</div>\n", styles: [":host{display:block;height:100%}.min-height-0{min-height:0!important}.border-end:last-child{border-right:0!important}.day-number{width:24px;height:24px;border-radius:50%;font-size:.85rem;font-weight:500;transition:background-color .2s}.day-number.today{background-color:var(--bs-primary);color:#fff}.event-spacer{height:20px;width:100%;pointer-events:none}.hover-bg:hover{background-color:var(--bs-secondary-bg-subtle)}.cursor-pointer{cursor:pointer}.has-interval{background-image:linear-gradient(to right,color-mix(in srgb,var(--interval-color) 12%,transparent) 0%,transparent 100%);border-left:3px solid var(--interval-color)!important}.cdk-drag-preview{box-shadow:0 .5rem 1rem #0000004d;border-radius:var(--bs-border-radius-sm)}\n"], dependencies: [{ kind: "directive", type: CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "component", type: CalendarEventComponent, selector: "rlb-calendar-event", inputs: ["event", "view"], outputs: ["event-click", "event-container-click"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "directive", type: CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "pipe", type: DateTzPipe, name: "dtz" }, { kind: "pipe", type: DayOfWeekPipe, name: "dayOfWeek" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3259
3271
  }
3260
3272
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: CalendarMonthGridComponent, decorators: [{
3261
3273
  type: Component,
3262
3274
  args: [{ selector: 'rlb-calendar-month-grid', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CdkDropListGroup, CdkDropList, CalendarEventComponent, CdkDrag, CdkDragPlaceholder, CdkDragPreview, DateTzPipe, DayOfWeekPipe], template: "<div class=\"d-flex flex-column w-100 bg-body user-select-none month-view-root\">\n <!-- 1. Header Row (Fixed) -->\n <div #headerRow class=\"d-flex flex-shrink-0 border-bottom bg-body-tertiary overflow-hidden\"\n [style.min-height.rem]=\"layout().minHeaderHeight\" [style.padding-right.px]=\"scrollbarWidth()\">\n @for (day of weekDaysHeader(); track day) {\n <div class=\"flex-fill text-center py-2 border-end fw-bold text-secondary text-uppercase w-0 my-auto h6\">\n {{ day | dayOfWeek:'short' }}\n </div>\n }\n </div>\n\n <!-- SCROLL CONTAINER -->\n <div #scrollBody class=\"calendar-scroller flex-grow-1 overflow-auto bg-body position-relative\"\n [style.max-height.rem]=\"layout().maxBodyHeight\" (scroll)=\"onBodyScroll($event)\">\n\n <!-- 2. Grid Body (Scrollable) -->\n <div class=\"d-flex flex-column flex-grow-1 border-start min-height-0\">\n\n <div class=\"d-flex flex-column\" cdkDropListGroup>\n @for (week of weeks(); track week) {\n <div class=\"d-flex border-bottom min-h-row\" style=\"flex: 1 0 auto;\" [style.min-height.px]=\"layout().rowHeight\">\n @for (slot of week; track slot) {\n <div class=\"flex-fill border-end p-1 d-flex flex-column position-relative\" style=\"width: 0\"\n [class.bg-light]=\"!isCurrentMonth(slot.date)\"\n [class.has-interval]=\"hasInterval(slot.date)\"\n [style.--interval-color]=\"getIntervalColor(slot.date)\"\n cdkDropList [cdkDropListData]=\"slot.date\"\n (cdkDropListDropped)=\"onEventDrop($event)\" (click)=\"eventClick.emit(undefined)\">\n <!-- Date Number -->\n <div class=\"d-flex justify-content-center mb-1\">\n <span class=\"day-number d-flex align-items-center justify-content-center\"\n [class.today]=\"isToday(slot.date)\">\n {{ slot.date | dtz:'DD' }}\n </span>\n </div>\n <!-- Events Stack -->\n <div class=\"d-flex flex-column gap-1 w-100\">\n @for (event of slot.events; track trackByEvent($index, event)) {\n <!-- Spacer -->\n @if (event.isSpacer) {\n <div class=\"event-spacer\"></div>\n }\n <!-- Event -->\n @if (!event.isSpacer) {\n <rlb-calendar-event [event]=\"event\" class=\"w-100\" cdkDrag [cdkDragData]=\"event\"\n (event-click)=\"eventClick.emit($event)\" [view]=\"view()\">\n <!-- Drag Preview (Optional but nice) -->\n <div *cdkDragPlaceholder style=\"opacity: 0\"></div>\n <ng-template cdkDragPreview matchSize class=\"rlb-calendar-drag-preview\">\n <rlb-calendar-event [event]=\"event\" [view]=\"view()\" style=\"box-sizing: border-box;\">\n </rlb-calendar-event>\n </ng-template>\n </rlb-calendar-event>\n }\n }\n </div>\n <!-- Overflow (+N more) -->\n @if (slot.hasOverflow) {\n <div class=\"mt-1 small text-secondary text-center cursor-pointer p-1 rounded hover-bg\"\n (click)=\"$event.stopPropagation(); eventContainerClick.emit(slot.overflowEvents)\">\n +{{ slot.overflowCount }} more\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n </div>\n</div>\n", styles: [":host{display:block;height:100%}.min-height-0{min-height:0!important}.border-end:last-child{border-right:0!important}.day-number{width:24px;height:24px;border-radius:50%;font-size:.85rem;font-weight:500;transition:background-color .2s}.day-number.today{background-color:var(--bs-primary);color:#fff}.event-spacer{height:20px;width:100%;pointer-events:none}.hover-bg:hover{background-color:var(--bs-secondary-bg-subtle)}.cursor-pointer{cursor:pointer}.has-interval{background-image:linear-gradient(to right,color-mix(in srgb,var(--interval-color) 12%,transparent) 0%,transparent 100%);border-left:3px solid var(--interval-color)!important}.cdk-drag-preview{box-shadow:0 .5rem 1rem #0000004d;border-radius:var(--bs-border-radius-sm)}\n"] }]
3263
- }], ctorParameters: () => [], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: true }] }], currentDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentDate", required: true }] }], events: [{ type: i0.Input, args: [{ isSignal: true, alias: "events", required: false }] }], intervals: [{ type: i0.Input, args: [{ isSignal: true, alias: "intervals", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }], eventClick: [{ type: i0.Output, args: ["event-click"] }], eventContainerClick: [{ type: i0.Output, args: ["event-container-click"] }], eventChange: [{ type: i0.Output, args: ["event-change"] }], scrollBodyRef: [{ type: i0.ViewChild, args: ['scrollBody', { isSignal: true }] }], headerRowRef: [{ type: i0.ViewChild, args: ['headerRow', { isSignal: true }] }] } });
3275
+ }], ctorParameters: () => [], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: true }] }], currentDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentDate", required: true }] }], events: [{ type: i0.Input, args: [{ isSignal: true, alias: "events", required: false }] }], intervals: [{ type: i0.Input, args: [{ isSignal: true, alias: "intervals", required: false }] }], timezone: [{ type: i0.Input, args: [{ isSignal: true, alias: "timezone", required: true }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }], eventClick: [{ type: i0.Output, args: ["event-click"] }], eventContainerClick: [{ type: i0.Output, args: ["event-container-click"] }], eventChange: [{ type: i0.Output, args: ["event-change"] }], scrollBodyRef: [{ type: i0.ViewChild, args: ['scrollBody', { isSignal: true }] }], headerRowRef: [{ type: i0.ViewChild, args: ['headerRow', { isSignal: true }] }] } });
3264
3276
 
3265
3277
  class CalendarDayGridComponent {
3266
3278
  constructor() {
@@ -3268,6 +3280,7 @@ class CalendarDayGridComponent {
3268
3280
  this.currentDate = input.required(...(ngDevMode ? [{ debugName: "currentDate" }] : /* istanbul ignore next */ []));
3269
3281
  this.events = input([], ...(ngDevMode ? [{ debugName: "events" }] : /* istanbul ignore next */ []));
3270
3282
  this.intervals = input([], ...(ngDevMode ? [{ debugName: "intervals" }] : /* istanbul ignore next */ []));
3283
+ this.timezone = input.required(...(ngDevMode ? [{ debugName: "timezone" }] : /* istanbul ignore next */ []));
3271
3284
  this.layout = input.required(...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
3272
3285
  this.eventClick = output({ alias: 'event-click' });
3273
3286
  this.eventContainerClick = output({ alias: 'event-container-click' });
@@ -3289,6 +3302,10 @@ class CalendarDayGridComponent {
3289
3302
  effect(() => {
3290
3303
  this.processAllEvents(this.events(), this.currentDate());
3291
3304
  });
3305
+ // Keep the "now" line in the calendar timezone.
3306
+ effect(() => {
3307
+ this.now.set(getToday(this.timezone()));
3308
+ });
3292
3309
  }
3293
3310
  ngAfterViewInit() { }
3294
3311
  ngOnDestroy() {
@@ -3307,13 +3324,12 @@ class CalendarDayGridComponent {
3307
3324
  const rawMinutesFromStart = (newTopPx / this.layout().rowHeight) * 60;
3308
3325
  const snappedMinutes = Math.round(rawMinutesFromStart / this.SNAP_MINUTES) * this.SNAP_MINUTES;
3309
3326
  const validMinutes = Math.max(0, snappedMinutes);
3310
- const newStart = new DateTz$1(newDay)
3311
- .set(0, 'hour')
3312
- .set(0, 'minute')
3313
- .add(validMinutes, 'minute')
3314
- .stripSecMillis();
3327
+ // Local midnight of the target day + dropped offset (tz-aware).
3328
+ const tz = this.timezone();
3329
+ const newStartTs = startOfDayTs(newDay, tz) + validMinutes * 60 * 1000;
3330
+ const newStart = new DateTz$1(newStartTs, tz).stripSecMillis();
3315
3331
  const durationMs = movedEvent.end.timestamp - movedEvent.start.timestamp;
3316
- const newEnd = new DateTz$1(newStart.timestamp + durationMs).stripSecMillis();
3332
+ const newEnd = new DateTz$1(newStart.timestamp + durationMs, tz).stripSecMillis();
3317
3333
  if (newStart.timestamp !== movedEvent.start.timestamp) {
3318
3334
  const updatedEvent = {
3319
3335
  ...movedEvent,
@@ -3324,16 +3340,9 @@ class CalendarDayGridComponent {
3324
3340
  }
3325
3341
  }
3326
3342
  calculateEventTop(event) {
3327
- const startOfDay = new DateTz$1(this.day()).set(0, 'hour').set(0, 'minute').stripSecMillis();
3328
- // Use event.start directly, but ensure we are calculating relative to THIS day
3329
- // If event starts on previous day, we should clamp?
3330
- // Logic from week grid handles "chunks", here we assume processAllEvents has given us the chunk for this day.
3331
- let eventStart = event.start;
3332
- if (eventStart.timestamp < startOfDay.timestamp) {
3333
- eventStart = startOfDay;
3334
- }
3335
- const diffMs = eventStart.timestamp - startOfDay.timestamp;
3336
- const diffMinutes = diffMs / (1000 * 60);
3343
+ // processAllEvents already clamped the event to this day, so its start is
3344
+ // within [00:00, 24:00) of the day. Minutes-since-local-midnight is tz-aware.
3345
+ const diffMinutes = minutesSinceMidnight(event.start, this.timezone());
3337
3346
  return (diffMinutes / 60) * this.layout().rowHeight;
3338
3347
  }
3339
3348
  calculateEventHeight(event) {
@@ -3350,12 +3359,12 @@ class CalendarDayGridComponent {
3350
3359
  return ((hours * 60) + minutes) / 60 * this.layout().rowHeight;
3351
3360
  }
3352
3361
  isToday(date) {
3353
- return isToday(date);
3362
+ return isToday(date, this.timezone());
3354
3363
  }
3355
3364
  startNowTimer() {
3356
3365
  this.stopNowTimer(); // clear existing if any
3357
3366
  this.nowInterval = setInterval(() => {
3358
- this.now.set(getToday());
3367
+ this.now.set(getToday(this.timezone()));
3359
3368
  }, 60 * 1000); // every minute
3360
3369
  }
3361
3370
  stopNowTimer() {
@@ -3380,7 +3389,8 @@ class CalendarDayGridComponent {
3380
3389
  return `var(--bs-${interval.color || 'success'})`;
3381
3390
  }
3382
3391
  buildDayGrid(currentDate) {
3383
- this.day.set(new DateTz$1(currentDate.timestamp, 'UTC'));
3392
+ // Anchor the day to local midnight in the calendar timezone.
3393
+ this.day.set(dayAt(currentDate, this.timezone(), 0));
3384
3394
  this.startNowTimer();
3385
3395
  }
3386
3396
  buildTimeSlots() {
@@ -3400,29 +3410,23 @@ class CalendarDayGridComponent {
3400
3410
  processAllEvents(events, day) {
3401
3411
  if (!day)
3402
3412
  return;
3403
- // Filter events for this day
3404
- const dayStart = new DateTz$1(day).set(0, 'hour').set(0, 'minute').stripSecMillis();
3405
- const dayEnd = new DateTz$1(day).set(0, 'hour').set(0, 'minute').add(1, 'day').stripSecMillis();
3413
+ const tz = this.timezone();
3414
+ // tz-aware day boundaries (set()/add() would be UTC-naive here).
3415
+ const dayStartTs = startOfDayTs(day, tz);
3416
+ const dayEndTs = dayAt(day, tz, 1).timestamp;
3406
3417
  const dayEvents = [];
3407
3418
  for (const event of events) {
3408
3419
  // Check overlap with the day
3409
- if (event.end.timestamp > dayStart.timestamp && event.start.timestamp < dayEnd.timestamp) {
3410
- let visualStart = event.start;
3411
- let visualEnd = event.end;
3412
- let isContinuedBefore = false;
3413
- let isContinuedAfter = false;
3414
- if (visualStart.timestamp < dayStart.timestamp) {
3415
- visualStart = dayStart;
3416
- isContinuedBefore = true;
3417
- }
3418
- if (visualEnd.timestamp > dayEnd.timestamp) {
3419
- visualEnd = dayEnd;
3420
- isContinuedAfter = true;
3421
- }
3420
+ if (event.end.timestamp > dayStartTs && event.start.timestamp < dayEndTs) {
3421
+ const isContinuedBefore = event.start.timestamp < dayStartTs;
3422
+ const isContinuedAfter = event.end.timestamp > dayEndTs;
3423
+ const visualStartTs = Math.max(event.start.timestamp, dayStartTs);
3424
+ const visualEndTs = Math.min(event.end.timestamp, dayEndTs);
3422
3425
  dayEvents.push({
3423
3426
  ...event,
3424
- start: visualStart,
3425
- end: visualEnd,
3427
+ // Chunks live in the calendar timezone, so labels and positions agree.
3428
+ start: new DateTz$1(visualStartTs, tz),
3429
+ end: new DateTz$1(visualEndTs, tz),
3426
3430
  isContinuedBefore,
3427
3431
  isContinuedAfter,
3428
3432
  left: 0,
@@ -3516,12 +3520,12 @@ class CalendarDayGridComponent {
3516
3520
  });
3517
3521
  }
3518
3522
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: CalendarDayGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3519
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: CalendarDayGridComponent, isStandalone: true, selector: "rlb-calendar-day-grid", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: true, transformFunction: null }, currentDate: { classPropertyName: "currentDate", publicName: "currentDate", isSignal: true, isRequired: true, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, intervals: { classPropertyName: "intervals", publicName: "intervals", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { eventClick: "event-click", eventContainerClick: "event-container-click", eventChange: "event-change" }, viewQueries: [{ propertyName: "scrollBodyRef", first: true, predicate: ["scrollBody"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (day()) {\n<div class=\"calendar-wrapper d-flex flex-column\">\n <!-- HEADER WRAPPER -->\n <!-- For day view, we just show the date at top? Or maybe just keep it simple with body since main header has date -->\n <!-- Mimicking structure of Week View but single column -->\n <div class=\"header-container overflow-hidden flex-shrink-0 border-bottom bg-body-tertiary\">\n <div class=\"header-row d-flex\" [style.min-height.rem]=\"layout().minHeaderHeight\">\n <div class=\"time-gutter border-end flex-shrink-0\"></div>\n <div class=\"day-cell p-2 flex-grow-1\" [class.text-primary]=\"isToday(day())\" [class.fw-bold]=\"isToday(day())\"\n [class.bg-primary]=\"isToday(day())\">\n <div class=\"small text-uppercase text-body-secondary h-100 d-flex align-items-center justify-content-center\">{{\n day() | dayOfWeek: 'long' }}</div>\n </div>\n </div>\n </div>\n <!-- BODY WRAPPER -->\n <div #scrollBody class=\"calendar-body flex-grow-1 overflow-auto bg-body position-relative\"\n [style.max-height.rem]=\"layout().maxBodyHeight\">\n <div class=\"body-row d-flex position-relative\">\n <!-- SIDEBAR (Sticky Left) -->\n <div class=\"time-sidebar sticky-start flex-shrink-0 border-end\">\n @for (time of timeSlots(); track time; let i = $index) {\n <div class=\"time-slot-label small text-body-secondary d-flex align-items-start justify-content-center\"\n [style.height.px]=\"layout().rowHeight\">\n @if (i !== 0) {\n <span style=\"transform: translateY(-50%)\">\n {{ time }}\n </span>\n }\n </div>\n }\n </div>\n <!-- GRID AND EVENTS -->\n <div class=\"grid-layer flex-grow-1 position-relative\">\n <!-- LAYER 1: Grid -->\n <div class=\"background-grid position-absolute w-100 h-100 top-0 start-0 z-0\">\n @for (time of timeSlots(); track time) {\n <div class=\"grid-row border-bottom\" [style.height.px]=\"layout().rowHeight\">\n </div>\n }\n </div>\n <!-- Layer 1.5: Intervals (background highlights) -->\n <div class=\"intervals-container position-absolute w-100 h-100 top-0 start-0\" style=\"z-index: 0; pointer-events: none;\">\n @for (interval of getIntervalsForDay(); track $index) {\n <div class=\"calendar-interval position-absolute w-100\"\n [style.top.px]=\"getIntervalTop(interval)\"\n [style.height.px]=\"getIntervalHeight(interval)\"\n [style.background-color]=\"getIntervalColor(interval)\">\n </div>\n }\n </div>\n\n <!-- Layer 2: Events -->\n <div class=\"events-container d-flex h-100 w-100 position-relative z-1\" cdkDropListGroup>\n <div class=\"day-column position-relative h-100 w-100\" cdkDropList [cdkDropListSortingDisabled]=\"true\"\n [cdkDropListData]=\"day()\" (cdkDropListDropped)=\"onEventDrop($event)\" (click)=\"eventClick.emit(undefined)\">\n @for (event of processedEvents(); track trackByEventId($index, event)) {\n <rlb-calendar-event [view]=\"view()\" [event]=\"event\" [style.top.px]=\"calculateEventTop(event)\"\n [style.height.px]=\"calculateEventHeight(event)\" [style.left.%]=\"event.left\" [style.width.%]=\"event.width\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\" cdkDrag\n [cdkDragData]=\"event\" class=\"position-absolute\">\n <div *cdkDragPlaceholder style=\"opacity: 0\"></div>\n </rlb-calendar-event>\n }\n @if (isToday(day())) {\n <div class=\"now-line\" [style.top.px]=\"getNowTop()\">\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n}\n", styles: [":host{display:block;height:100%}.calendar-wrapper{background-color:var(--bs-body-bg);border:1px solid var(--bs-border-color);border-radius:var(--bs-border-radius);overflow:hidden;height:100%}.header-container{background-color:var(--bs-body-bg);z-index:102}.header-row{width:100%}.time-gutter{width:60px;border-color:var(--bs-border-color)!important}.day-cell{border-color:var(--bs-border-color)!important}.calendar-body{scroll-behavior:auto}.body-row{width:100%}.sticky-start{position:sticky;left:0;z-index:50;background-color:var(--bs-body-bg)}.time-sidebar{width:60px;border-color:var(--bs-border-color)!important}.grid-row{border-color:var(--bs-border-color)!important;box-sizing:border-box}.grid-row:after{content:\"\";position:absolute;width:100%;border-bottom:1px dotted currentColor;opacity:.15;top:50%;left:0;pointer-events:none}.now-line{position:absolute;left:0;right:0;height:2px;background-color:var(--bs-danger);z-index:10;pointer-events:none}.now-line:before{content:\"\";position:absolute;left:-5px;top:-4px;width:10px;height:10px;background-color:var(--bs-danger);border-radius:50%}.calendar-interval{opacity:.1;pointer-events:none;border-radius:0}.z-0{z-index:0}.z-1{z-index:1}\n"], dependencies: [{ kind: "directive", type: CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "component", type: CalendarEventComponent, selector: "rlb-calendar-event", inputs: ["event", "view"], outputs: ["event-click", "event-container-click"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "pipe", type: DayOfWeekPipe, name: "dayOfWeek" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3523
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: CalendarDayGridComponent, isStandalone: true, selector: "rlb-calendar-day-grid", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: true, transformFunction: null }, currentDate: { classPropertyName: "currentDate", publicName: "currentDate", isSignal: true, isRequired: true, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, intervals: { classPropertyName: "intervals", publicName: "intervals", isSignal: true, isRequired: false, transformFunction: null }, timezone: { classPropertyName: "timezone", publicName: "timezone", isSignal: true, isRequired: true, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { eventClick: "event-click", eventContainerClick: "event-container-click", eventChange: "event-change" }, viewQueries: [{ propertyName: "scrollBodyRef", first: true, predicate: ["scrollBody"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (day()) {\n<div class=\"calendar-wrapper d-flex flex-column\">\n <!-- HEADER WRAPPER -->\n <!-- For day view, we just show the date at top? Or maybe just keep it simple with body since main header has date -->\n <!-- Mimicking structure of Week View but single column -->\n <div class=\"header-container overflow-hidden flex-shrink-0 border-bottom bg-body-tertiary\">\n <div class=\"header-row d-flex\" [style.min-height.rem]=\"layout().minHeaderHeight\">\n <div class=\"time-gutter border-end flex-shrink-0\"></div>\n <div class=\"day-cell p-2 flex-grow-1\" [class.text-primary]=\"isToday(day())\" [class.fw-bold]=\"isToday(day())\"\n [class.bg-primary]=\"isToday(day())\">\n <div class=\"small text-uppercase text-body-secondary h-100 d-flex align-items-center justify-content-center\">{{\n day() | dayOfWeek: 'long' }}</div>\n </div>\n </div>\n </div>\n <!-- BODY WRAPPER -->\n <div #scrollBody class=\"calendar-body flex-grow-1 overflow-auto bg-body position-relative\"\n [style.max-height.rem]=\"layout().maxBodyHeight\">\n <div class=\"body-row d-flex position-relative\">\n <!-- SIDEBAR (Sticky Left) -->\n <div class=\"time-sidebar sticky-start flex-shrink-0 border-end\">\n @for (time of timeSlots(); track time; let i = $index) {\n <div class=\"time-slot-label small text-body-secondary d-flex align-items-start justify-content-center\"\n [style.height.px]=\"layout().rowHeight\">\n @if (i !== 0) {\n <span style=\"transform: translateY(-50%)\">\n {{ time }}\n </span>\n }\n </div>\n }\n </div>\n <!-- GRID AND EVENTS -->\n <div class=\"grid-layer flex-grow-1 position-relative\">\n <!-- LAYER 1: Grid -->\n <div class=\"background-grid position-absolute w-100 h-100 top-0 start-0 z-0\">\n @for (time of timeSlots(); track time) {\n <div class=\"grid-row border-bottom\" [style.height.px]=\"layout().rowHeight\">\n </div>\n }\n </div>\n <!-- Layer 1.5: Intervals (background highlights) -->\n <div class=\"intervals-container position-absolute w-100 h-100 top-0 start-0\" style=\"z-index: 0; pointer-events: none;\">\n @for (interval of getIntervalsForDay(); track $index) {\n <div class=\"calendar-interval position-absolute w-100\"\n [style.top.px]=\"getIntervalTop(interval)\"\n [style.height.px]=\"getIntervalHeight(interval)\"\n [style.background-color]=\"getIntervalColor(interval)\">\n </div>\n }\n </div>\n\n <!-- Layer 2: Events -->\n <div class=\"events-container d-flex h-100 w-100 position-relative z-1\" cdkDropListGroup>\n <div class=\"day-column position-relative h-100 w-100\" cdkDropList [cdkDropListSortingDisabled]=\"true\"\n [cdkDropListData]=\"day()\" (cdkDropListDropped)=\"onEventDrop($event)\" (click)=\"eventClick.emit(undefined)\">\n @for (event of processedEvents(); track trackByEventId($index, event)) {\n <rlb-calendar-event [view]=\"view()\" [event]=\"event\" [style.top.px]=\"calculateEventTop(event)\"\n [style.height.px]=\"calculateEventHeight(event)\" [style.left.%]=\"event.left\" [style.width.%]=\"event.width\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\" cdkDrag\n [cdkDragData]=\"event\" class=\"position-absolute\">\n <div *cdkDragPlaceholder style=\"opacity: 0\"></div>\n </rlb-calendar-event>\n }\n @if (isToday(day())) {\n <div class=\"now-line\" [style.top.px]=\"getNowTop()\">\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n}\n", styles: [":host{display:block;height:100%}.calendar-wrapper{background-color:var(--bs-body-bg);border:1px solid var(--bs-border-color);border-radius:var(--bs-border-radius);overflow:hidden;height:100%}.header-container{background-color:var(--bs-body-bg);z-index:102}.header-row{width:100%}.time-gutter{width:60px;border-color:var(--bs-border-color)!important}.day-cell{border-color:var(--bs-border-color)!important}.calendar-body{scroll-behavior:auto}.body-row{width:100%}.sticky-start{position:sticky;left:0;z-index:50;background-color:var(--bs-body-bg)}.time-sidebar{width:60px;border-color:var(--bs-border-color)!important}.grid-row{border-color:var(--bs-border-color)!important;box-sizing:border-box}.grid-row:after{content:\"\";position:absolute;width:100%;border-bottom:1px dotted currentColor;opacity:.15;top:50%;left:0;pointer-events:none}.now-line{position:absolute;left:0;right:0;height:2px;background-color:var(--bs-danger);z-index:10;pointer-events:none}.now-line:before{content:\"\";position:absolute;left:-5px;top:-4px;width:10px;height:10px;background-color:var(--bs-danger);border-radius:50%}.calendar-interval{opacity:.1;pointer-events:none;border-radius:0}.z-0{z-index:0}.z-1{z-index:1}\n"], dependencies: [{ kind: "directive", type: CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "component", type: CalendarEventComponent, selector: "rlb-calendar-event", inputs: ["event", "view"], outputs: ["event-click", "event-container-click"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "pipe", type: DayOfWeekPipe, name: "dayOfWeek" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3520
3524
  }
3521
3525
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: CalendarDayGridComponent, decorators: [{
3522
3526
  type: Component,
3523
3527
  args: [{ selector: 'rlb-calendar-day-grid', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CdkDropListGroup, CdkDropList, CalendarEventComponent, CdkDrag, CdkDragPlaceholder, DayOfWeekPipe], template: "@if (day()) {\n<div class=\"calendar-wrapper d-flex flex-column\">\n <!-- HEADER WRAPPER -->\n <!-- For day view, we just show the date at top? Or maybe just keep it simple with body since main header has date -->\n <!-- Mimicking structure of Week View but single column -->\n <div class=\"header-container overflow-hidden flex-shrink-0 border-bottom bg-body-tertiary\">\n <div class=\"header-row d-flex\" [style.min-height.rem]=\"layout().minHeaderHeight\">\n <div class=\"time-gutter border-end flex-shrink-0\"></div>\n <div class=\"day-cell p-2 flex-grow-1\" [class.text-primary]=\"isToday(day())\" [class.fw-bold]=\"isToday(day())\"\n [class.bg-primary]=\"isToday(day())\">\n <div class=\"small text-uppercase text-body-secondary h-100 d-flex align-items-center justify-content-center\">{{\n day() | dayOfWeek: 'long' }}</div>\n </div>\n </div>\n </div>\n <!-- BODY WRAPPER -->\n <div #scrollBody class=\"calendar-body flex-grow-1 overflow-auto bg-body position-relative\"\n [style.max-height.rem]=\"layout().maxBodyHeight\">\n <div class=\"body-row d-flex position-relative\">\n <!-- SIDEBAR (Sticky Left) -->\n <div class=\"time-sidebar sticky-start flex-shrink-0 border-end\">\n @for (time of timeSlots(); track time; let i = $index) {\n <div class=\"time-slot-label small text-body-secondary d-flex align-items-start justify-content-center\"\n [style.height.px]=\"layout().rowHeight\">\n @if (i !== 0) {\n <span style=\"transform: translateY(-50%)\">\n {{ time }}\n </span>\n }\n </div>\n }\n </div>\n <!-- GRID AND EVENTS -->\n <div class=\"grid-layer flex-grow-1 position-relative\">\n <!-- LAYER 1: Grid -->\n <div class=\"background-grid position-absolute w-100 h-100 top-0 start-0 z-0\">\n @for (time of timeSlots(); track time) {\n <div class=\"grid-row border-bottom\" [style.height.px]=\"layout().rowHeight\">\n </div>\n }\n </div>\n <!-- Layer 1.5: Intervals (background highlights) -->\n <div class=\"intervals-container position-absolute w-100 h-100 top-0 start-0\" style=\"z-index: 0; pointer-events: none;\">\n @for (interval of getIntervalsForDay(); track $index) {\n <div class=\"calendar-interval position-absolute w-100\"\n [style.top.px]=\"getIntervalTop(interval)\"\n [style.height.px]=\"getIntervalHeight(interval)\"\n [style.background-color]=\"getIntervalColor(interval)\">\n </div>\n }\n </div>\n\n <!-- Layer 2: Events -->\n <div class=\"events-container d-flex h-100 w-100 position-relative z-1\" cdkDropListGroup>\n <div class=\"day-column position-relative h-100 w-100\" cdkDropList [cdkDropListSortingDisabled]=\"true\"\n [cdkDropListData]=\"day()\" (cdkDropListDropped)=\"onEventDrop($event)\" (click)=\"eventClick.emit(undefined)\">\n @for (event of processedEvents(); track trackByEventId($index, event)) {\n <rlb-calendar-event [view]=\"view()\" [event]=\"event\" [style.top.px]=\"calculateEventTop(event)\"\n [style.height.px]=\"calculateEventHeight(event)\" [style.left.%]=\"event.left\" [style.width.%]=\"event.width\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\" cdkDrag\n [cdkDragData]=\"event\" class=\"position-absolute\">\n <div *cdkDragPlaceholder style=\"opacity: 0\"></div>\n </rlb-calendar-event>\n }\n @if (isToday(day())) {\n <div class=\"now-line\" [style.top.px]=\"getNowTop()\">\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n}\n", styles: [":host{display:block;height:100%}.calendar-wrapper{background-color:var(--bs-body-bg);border:1px solid var(--bs-border-color);border-radius:var(--bs-border-radius);overflow:hidden;height:100%}.header-container{background-color:var(--bs-body-bg);z-index:102}.header-row{width:100%}.time-gutter{width:60px;border-color:var(--bs-border-color)!important}.day-cell{border-color:var(--bs-border-color)!important}.calendar-body{scroll-behavior:auto}.body-row{width:100%}.sticky-start{position:sticky;left:0;z-index:50;background-color:var(--bs-body-bg)}.time-sidebar{width:60px;border-color:var(--bs-border-color)!important}.grid-row{border-color:var(--bs-border-color)!important;box-sizing:border-box}.grid-row:after{content:\"\";position:absolute;width:100%;border-bottom:1px dotted currentColor;opacity:.15;top:50%;left:0;pointer-events:none}.now-line{position:absolute;left:0;right:0;height:2px;background-color:var(--bs-danger);z-index:10;pointer-events:none}.now-line:before{content:\"\";position:absolute;left:-5px;top:-4px;width:10px;height:10px;background-color:var(--bs-danger);border-radius:50%}.calendar-interval{opacity:.1;pointer-events:none;border-radius:0}.z-0{z-index:0}.z-1{z-index:1}\n"] }]
3524
- }], ctorParameters: () => [], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: true }] }], currentDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentDate", required: true }] }], events: [{ type: i0.Input, args: [{ isSignal: true, alias: "events", required: false }] }], intervals: [{ type: i0.Input, args: [{ isSignal: true, alias: "intervals", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }], eventClick: [{ type: i0.Output, args: ["event-click"] }], eventContainerClick: [{ type: i0.Output, args: ["event-container-click"] }], eventChange: [{ type: i0.Output, args: ["event-change"] }], scrollBodyRef: [{ type: i0.ViewChild, args: ['scrollBody', { isSignal: true }] }] } });
3528
+ }], ctorParameters: () => [], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: true }] }], currentDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentDate", required: true }] }], events: [{ type: i0.Input, args: [{ isSignal: true, alias: "events", required: false }] }], intervals: [{ type: i0.Input, args: [{ isSignal: true, alias: "intervals", required: false }] }], timezone: [{ type: i0.Input, args: [{ isSignal: true, alias: "timezone", required: true }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }], eventClick: [{ type: i0.Output, args: ["event-click"] }], eventContainerClick: [{ type: i0.Output, args: ["event-container-click"] }], eventChange: [{ type: i0.Output, args: ["event-change"] }], scrollBodyRef: [{ type: i0.ViewChild, args: ['scrollBody', { isSignal: true }] }] } });
3525
3529
 
3526
3530
  class CalendarGrid {
3527
3531
  constructor() {
@@ -3529,6 +3533,7 @@ class CalendarGrid {
3529
3533
  this.currentDate = input.required(...(ngDevMode ? [{ debugName: "currentDate" }] : /* istanbul ignore next */ []));
3530
3534
  this.events = input([], ...(ngDevMode ? [{ debugName: "events" }] : /* istanbul ignore next */ []));
3531
3535
  this.intervals = input([], ...(ngDevMode ? [{ debugName: "intervals" }] : /* istanbul ignore next */ []));
3536
+ this.timezone = input.required(...(ngDevMode ? [{ debugName: "timezone" }] : /* istanbul ignore next */ []));
3532
3537
  this.layout = input.required(...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
3533
3538
  this.eventClick = output({ alias: 'event-click' });
3534
3539
  this.eventContainerClick = output({ alias: 'event-container-click' });
@@ -3536,7 +3541,7 @@ class CalendarGrid {
3536
3541
  }
3537
3542
  ngOnDestroy() { }
3538
3543
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: CalendarGrid, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3539
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: CalendarGrid, isStandalone: true, selector: "rlb-calendar-grid", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: true, transformFunction: null }, currentDate: { classPropertyName: "currentDate", publicName: "currentDate", isSignal: true, isRequired: true, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, intervals: { classPropertyName: "intervals", publicName: "intervals", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { eventClick: "event-click", eventContainerClick: "event-container-click", eventChange: "event-change" }, ngImport: i0, template: "@switch (view()) {\n@case ('week') {\n<rlb-calendar-week-grid [view]=\"view()\" [currentDate]=\"currentDate()\" [events]=\"events()\" [intervals]=\"intervals()\" [layout]=\"layout()\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\"\n (event-change)=\"eventChange.emit($event)\" />\n}\n@case ('month') {\n<rlb-calendar-month-grid [view]=\"view()\" [currentDate]=\"currentDate()\" [events]=\"events()\" [intervals]=\"intervals()\" [layout]=\"layout()\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\"\n (event-change)=\"eventChange.emit($event)\" />\n}\n@case ('day') {\n<rlb-calendar-day-grid [view]=\"view()\" [currentDate]=\"currentDate()\" [events]=\"events()\" [intervals]=\"intervals()\" [layout]=\"layout()\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\"\n (event-change)=\"eventChange.emit($event)\" />\n}\n@default {\nnot implemented yet\n}\n}\n", styles: [""], dependencies: [{ kind: "component", type: CalendarWeekGridComponent, selector: "rlb-calendar-week-grid", inputs: ["view", "currentDate", "events", "intervals", "layout"], outputs: ["event-click", "event-container-click", "event-change"] }, { kind: "component", type: CalendarMonthGridComponent, selector: "rlb-calendar-month-grid", inputs: ["view", "currentDate", "events", "intervals", "layout"], outputs: ["event-click", "event-container-click", "event-change"] }, { kind: "component", type: CalendarDayGridComponent, selector: "rlb-calendar-day-grid", inputs: ["view", "currentDate", "events", "intervals", "layout"], outputs: ["event-click", "event-container-click", "event-change"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3544
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: CalendarGrid, isStandalone: true, selector: "rlb-calendar-grid", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: true, transformFunction: null }, currentDate: { classPropertyName: "currentDate", publicName: "currentDate", isSignal: true, isRequired: true, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, intervals: { classPropertyName: "intervals", publicName: "intervals", isSignal: true, isRequired: false, transformFunction: null }, timezone: { classPropertyName: "timezone", publicName: "timezone", isSignal: true, isRequired: true, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { eventClick: "event-click", eventContainerClick: "event-container-click", eventChange: "event-change" }, ngImport: i0, template: "@switch (view()) {\n@case ('week') {\n<rlb-calendar-week-grid [view]=\"view()\" [currentDate]=\"currentDate()\" [events]=\"events()\" [intervals]=\"intervals()\" [timezone]=\"timezone()\" [layout]=\"layout()\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\"\n (event-change)=\"eventChange.emit($event)\" />\n}\n@case ('month') {\n<rlb-calendar-month-grid [view]=\"view()\" [currentDate]=\"currentDate()\" [events]=\"events()\" [intervals]=\"intervals()\" [timezone]=\"timezone()\" [layout]=\"layout()\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\"\n (event-change)=\"eventChange.emit($event)\" />\n}\n@case ('day') {\n<rlb-calendar-day-grid [view]=\"view()\" [currentDate]=\"currentDate()\" [events]=\"events()\" [intervals]=\"intervals()\" [timezone]=\"timezone()\" [layout]=\"layout()\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\"\n (event-change)=\"eventChange.emit($event)\" />\n}\n@default {\nnot implemented yet\n}\n}\n", styles: [""], dependencies: [{ kind: "component", type: CalendarWeekGridComponent, selector: "rlb-calendar-week-grid", inputs: ["view", "currentDate", "events", "intervals", "timezone", "layout"], outputs: ["event-click", "event-container-click", "event-change"] }, { kind: "component", type: CalendarMonthGridComponent, selector: "rlb-calendar-month-grid", inputs: ["view", "currentDate", "events", "intervals", "timezone", "layout"], outputs: ["event-click", "event-container-click", "event-change"] }, { kind: "component", type: CalendarDayGridComponent, selector: "rlb-calendar-day-grid", inputs: ["view", "currentDate", "events", "intervals", "timezone", "layout"], outputs: ["event-click", "event-container-click", "event-change"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3540
3545
  }
3541
3546
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: CalendarGrid, decorators: [{
3542
3547
  type: Component,
@@ -3544,8 +3549,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
3544
3549
  CalendarWeekGridComponent,
3545
3550
  CalendarMonthGridComponent,
3546
3551
  CalendarDayGridComponent,
3547
- ], template: "@switch (view()) {\n@case ('week') {\n<rlb-calendar-week-grid [view]=\"view()\" [currentDate]=\"currentDate()\" [events]=\"events()\" [intervals]=\"intervals()\" [layout]=\"layout()\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\"\n (event-change)=\"eventChange.emit($event)\" />\n}\n@case ('month') {\n<rlb-calendar-month-grid [view]=\"view()\" [currentDate]=\"currentDate()\" [events]=\"events()\" [intervals]=\"intervals()\" [layout]=\"layout()\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\"\n (event-change)=\"eventChange.emit($event)\" />\n}\n@case ('day') {\n<rlb-calendar-day-grid [view]=\"view()\" [currentDate]=\"currentDate()\" [events]=\"events()\" [intervals]=\"intervals()\" [layout]=\"layout()\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\"\n (event-change)=\"eventChange.emit($event)\" />\n}\n@default {\nnot implemented yet\n}\n}\n" }]
3548
- }], ctorParameters: () => [], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: true }] }], currentDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentDate", required: true }] }], events: [{ type: i0.Input, args: [{ isSignal: true, alias: "events", required: false }] }], intervals: [{ type: i0.Input, args: [{ isSignal: true, alias: "intervals", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }], eventClick: [{ type: i0.Output, args: ["event-click"] }], eventContainerClick: [{ type: i0.Output, args: ["event-container-click"] }], eventChange: [{ type: i0.Output, args: ["event-change"] }] } });
3552
+ ], template: "@switch (view()) {\n@case ('week') {\n<rlb-calendar-week-grid [view]=\"view()\" [currentDate]=\"currentDate()\" [events]=\"events()\" [intervals]=\"intervals()\" [timezone]=\"timezone()\" [layout]=\"layout()\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\"\n (event-change)=\"eventChange.emit($event)\" />\n}\n@case ('month') {\n<rlb-calendar-month-grid [view]=\"view()\" [currentDate]=\"currentDate()\" [events]=\"events()\" [intervals]=\"intervals()\" [timezone]=\"timezone()\" [layout]=\"layout()\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\"\n (event-change)=\"eventChange.emit($event)\" />\n}\n@case ('day') {\n<rlb-calendar-day-grid [view]=\"view()\" [currentDate]=\"currentDate()\" [events]=\"events()\" [intervals]=\"intervals()\" [timezone]=\"timezone()\" [layout]=\"layout()\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\"\n (event-change)=\"eventChange.emit($event)\" />\n}\n@default {\nnot implemented yet\n}\n}\n" }]
3553
+ }], ctorParameters: () => [], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: true }] }], currentDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentDate", required: true }] }], events: [{ type: i0.Input, args: [{ isSignal: true, alias: "events", required: false }] }], intervals: [{ type: i0.Input, args: [{ isSignal: true, alias: "intervals", required: false }] }], timezone: [{ type: i0.Input, args: [{ isSignal: true, alias: "timezone", required: true }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }], eventClick: [{ type: i0.Output, args: ["event-click"] }], eventContainerClick: [{ type: i0.Output, args: ["event-container-click"] }], eventChange: [{ type: i0.Output, args: ["event-change"] }] } });
3549
3554
 
3550
3555
  class MonthFormatterPipe {
3551
3556
  constructor() {
@@ -3578,6 +3583,7 @@ class CalendarHeaderComponent {
3578
3583
  constructor() {
3579
3584
  this.view = input('month', ...(ngDevMode ? [{ debugName: "view" }] : /* istanbul ignore next */ []));
3580
3585
  this.currentDate = input.required(...(ngDevMode ? [{ debugName: "currentDate" }] : /* istanbul ignore next */ []));
3586
+ this.timezone = input.required(...(ngDevMode ? [{ debugName: "timezone" }] : /* istanbul ignore next */ []));
3581
3587
  this.dateChange = output();
3582
3588
  this.viewChange = output();
3583
3589
  }
@@ -3621,7 +3627,7 @@ class CalendarHeaderComponent {
3621
3627
  switch (this.view()) {
3622
3628
  case 'week':
3623
3629
  default:
3624
- const today = getToday();
3630
+ const today = getToday(this.timezone());
3625
3631
  this.dateChange.emit(today);
3626
3632
  break;
3627
3633
  }
@@ -3630,7 +3636,7 @@ class CalendarHeaderComponent {
3630
3636
  this.viewChange.emit(view);
3631
3637
  }
3632
3638
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: CalendarHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3633
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.15", type: CalendarHeaderComponent, isStandalone: true, selector: "rlb-calendar-header", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null }, currentDate: { classPropertyName: "currentDate", publicName: "currentDate", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { dateChange: "dateChange", viewChange: "viewChange" }, ngImport: i0, template: "<div class=\"d-flex justify-content-between align-items-center mb-3\">\n\t<div class=\"d-flex gap-1\">\n\t\t<button rlb-button outline (click)=\"prev()\">\n\t\t\t<i class=\"bi bi-chevron-left\"></i>\n\t\t</button>\n\t\t<button rlb-button outline (click)=\"today()\">Today</button>\n\t\t<button rlb-button outline (click)=\"next()\">\n\t\t\t<i class=\"bi-chevron-right\"></i>\n\t\t</button>\n\t</div>\n\n\t<h5 class=\"mb-0\">{{ currentDate() | dtz:'DD MM yyyy' | monthFormatter }} {{ currentDate().timezone }}</h5>\n\n\t<rlb-dropdown>\n\t\t<button rlb-button outline rlb-dropdown>{{ view() | titlecase }}</button>\n\t\t<ul rlb-dropdown-menu [placement]=\"'right'\">\n\t\t\t<li rlb-dropdown-item (click)=\"setView('day')\">Day</li>\n\t\t\t<li rlb-dropdown-item (click)=\"setView('week')\">Week</li>\n\t\t\t<li rlb-dropdown-item (click)=\"setView('month')\">Month</li>\n\t\t</ul>\n\t</rlb-dropdown>\n</div>", styles: [""], dependencies: [{ kind: "component", type: ButtonComponent, selector: "button[rlb-button], a[rlb-button]", inputs: ["color", "size", "disabled", "outline", "isLink"] }, { kind: "component", type: DropdownComponent, selector: "rlb-dropdown", inputs: ["direction"] }, { kind: "directive", type: DropdownDirective, selector: "a[rlb-dropdown], button[rlb-dropdown], span[rlb-badge][rlb-dropdown]", inputs: ["offset", "auto-close"], outputs: ["status-changed"] }, { kind: "component", type: DropdownContainerComponent, selector: "ul[rlb-dropdown-menu], rlb-dropdown-container", inputs: ["placement", "placement-sm", "placement-md", "placement-lg", "placement-xl", "placement-xxl"] }, { kind: "component", type: DropdownMenuItemComponent, selector: "li[rlb-dropdown-item]", inputs: ["active", "disabled", "header", "divider", "link", "text-wrap"] }, { kind: "pipe", type: TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: DateTzPipe, name: "dtz" }, { kind: "pipe", type: MonthFormatterPipe, name: "monthFormatter" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3639
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.15", type: CalendarHeaderComponent, isStandalone: true, selector: "rlb-calendar-header", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null }, currentDate: { classPropertyName: "currentDate", publicName: "currentDate", isSignal: true, isRequired: true, transformFunction: null }, timezone: { classPropertyName: "timezone", publicName: "timezone", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { dateChange: "dateChange", viewChange: "viewChange" }, ngImport: i0, template: "<div class=\"d-flex justify-content-between align-items-center mb-3\">\n\t<div class=\"d-flex gap-1\">\n\t\t<button rlb-button outline (click)=\"prev()\">\n\t\t\t<i class=\"bi bi-chevron-left\"></i>\n\t\t</button>\n\t\t<button rlb-button outline (click)=\"today()\">Today</button>\n\t\t<button rlb-button outline (click)=\"next()\">\n\t\t\t<i class=\"bi-chevron-right\"></i>\n\t\t</button>\n\t</div>\n\n\t<h5 class=\"mb-0\">{{ currentDate() | dtz:'DD MM yyyy' | monthFormatter }} {{ currentDate().timezone }}</h5>\n\n\t<rlb-dropdown>\n\t\t<button rlb-button outline rlb-dropdown>{{ view() | titlecase }}</button>\n\t\t<ul rlb-dropdown-menu [placement]=\"'right'\">\n\t\t\t<li rlb-dropdown-item (click)=\"setView('day')\">Day</li>\n\t\t\t<li rlb-dropdown-item (click)=\"setView('week')\">Week</li>\n\t\t\t<li rlb-dropdown-item (click)=\"setView('month')\">Month</li>\n\t\t</ul>\n\t</rlb-dropdown>\n</div>", styles: [""], dependencies: [{ kind: "component", type: ButtonComponent, selector: "button[rlb-button], a[rlb-button]", inputs: ["color", "size", "disabled", "outline", "isLink"] }, { kind: "component", type: DropdownComponent, selector: "rlb-dropdown", inputs: ["direction"] }, { kind: "directive", type: DropdownDirective, selector: "a[rlb-dropdown], button[rlb-dropdown], span[rlb-badge][rlb-dropdown]", inputs: ["offset", "auto-close"], outputs: ["status-changed"] }, { kind: "component", type: DropdownContainerComponent, selector: "ul[rlb-dropdown-menu], rlb-dropdown-container", inputs: ["placement", "placement-sm", "placement-md", "placement-lg", "placement-xl", "placement-xxl"] }, { kind: "component", type: DropdownMenuItemComponent, selector: "li[rlb-dropdown-item]", inputs: ["active", "disabled", "header", "divider", "link", "text-wrap"] }, { kind: "pipe", type: TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: DateTzPipe, name: "dtz" }, { kind: "pipe", type: MonthFormatterPipe, name: "monthFormatter" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3634
3640
  }
3635
3641
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: CalendarHeaderComponent, decorators: [{
3636
3642
  type: Component,
@@ -3644,7 +3650,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
3644
3650
  DateTzPipe,
3645
3651
  MonthFormatterPipe,
3646
3652
  ], template: "<div class=\"d-flex justify-content-between align-items-center mb-3\">\n\t<div class=\"d-flex gap-1\">\n\t\t<button rlb-button outline (click)=\"prev()\">\n\t\t\t<i class=\"bi bi-chevron-left\"></i>\n\t\t</button>\n\t\t<button rlb-button outline (click)=\"today()\">Today</button>\n\t\t<button rlb-button outline (click)=\"next()\">\n\t\t\t<i class=\"bi-chevron-right\"></i>\n\t\t</button>\n\t</div>\n\n\t<h5 class=\"mb-0\">{{ currentDate() | dtz:'DD MM yyyy' | monthFormatter }} {{ currentDate().timezone }}</h5>\n\n\t<rlb-dropdown>\n\t\t<button rlb-button outline rlb-dropdown>{{ view() | titlecase }}</button>\n\t\t<ul rlb-dropdown-menu [placement]=\"'right'\">\n\t\t\t<li rlb-dropdown-item (click)=\"setView('day')\">Day</li>\n\t\t\t<li rlb-dropdown-item (click)=\"setView('week')\">Week</li>\n\t\t\t<li rlb-dropdown-item (click)=\"setView('month')\">Month</li>\n\t\t</ul>\n\t</rlb-dropdown>\n</div>" }]
3647
- }], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: false }] }], currentDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentDate", required: true }] }], dateChange: [{ type: i0.Output, args: ["dateChange"] }], viewChange: [{ type: i0.Output, args: ["viewChange"] }] } });
3653
+ }], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: false }] }], currentDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentDate", required: true }] }], timezone: [{ type: i0.Input, args: [{ isSignal: true, alias: "timezone", required: true }] }], dateChange: [{ type: i0.Output, args: ["dateChange"] }], viewChange: [{ type: i0.Output, args: ["viewChange"] }] } });
3648
3654
 
3649
3655
  const DEFAULT_CALENDAR_LAYOUT = {
3650
3656
  rowHeight: 110,
@@ -3890,6 +3896,7 @@ class CalendarComponent {
3890
3896
  this.events = model([], { ...(ngDevMode ? { debugName: "events" } : /* istanbul ignore next */ {}), alias: 'events' });
3891
3897
  this.currentDate = model(getToday(), { ...(ngDevMode ? { debugName: "currentDate" } : /* istanbul ignore next */ {}), alias: 'current-date' });
3892
3898
  // currentDateChange = output<IDateTz>({ alias: 'current-date-change' });
3899
+ this.timezone = input(getBrowserTimezone(), { ...(ngDevMode ? { debugName: "timezone" } : /* istanbul ignore next */ {}), alias: 'timezone' });
3893
3900
  this.loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), alias: 'loading', transform: booleanAttribute });
3894
3901
  this.showToolbar = input(true, { ...(ngDevMode ? { debugName: "showToolbar" } : /* istanbul ignore next */ {}), alias: 'show-toolbar',
3895
3902
  transform: booleanAttribute });
@@ -4073,7 +4080,7 @@ class CalendarComponent {
4073
4080
  .pipe(take(1));
4074
4081
  }
4075
4082
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: CalendarComponent, deps: [{ token: ModalService }, { token: UniqueIdService }, { token: ToastService }], target: i0.ɵɵFactoryTarget.Component }); }
4076
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: CalendarComponent, isStandalone: true, selector: "rlb-calendar", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, currentDate: { classPropertyName: "currentDate", publicName: "current-date", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, showToolbar: { classPropertyName: "showToolbar", publicName: "show-toolbar", isSignal: true, isRequired: false, transformFunction: null }, intervals: { classPropertyName: "intervals", publicName: "intervals", isSignal: true, isRequired: false, transformFunction: null }, manageEvents: { classPropertyName: "manageEvents", publicName: "manage-events", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { view: "viewChange", events: "eventsChange", currentDate: "current-dateChange", dateChange: "date-change", viewChange: "view-change", eventClick: "event-click", containerEventClick: "container-event-click" }, ngImport: i0, template: "<div class=\"rlb-calendar\">\n\n @if (showToolbar()) {\n <rlb-calendar-header\n [view]=\"view()\"\n [currentDate]=\"currentDate()\"\n (viewChange)=\"setView($event)\"\n (dateChange)=\"setDate($event)\"\n >\n </rlb-calendar-header>\n }\n\n @if (loading()) {\n <rlb-progress [infinite]=\"true\" [animated]=\"true\" [height]=\"3\" [showValue]=\"false\">\n </rlb-progress>\n } @else {\n <rlb-calendar-grid\n [events]=\"events()\"\n [intervals]=\"intervals()\"\n [view]=\"view()\"\n [currentDate]=\"currentDate()\"\n [layout]=\"mergedLayout()\"\n (event-click)=\"onEventClick($event)\"\n (event-container-click)=\"onEventContainerClick($event)\"\n (event-change)=\"onEventChange($event)\"\n >\n </rlb-calendar-grid>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: CalendarHeaderComponent, selector: "rlb-calendar-header", inputs: ["view", "currentDate"], outputs: ["dateChange", "viewChange"] }, { kind: "component", type: ProgressComponent, selector: "rlb-progress", inputs: ["max", "min", "value", "height", "animated", "striped", "infinite", "aria-label", "showValue", "color", "text-color"] }, { kind: "component", type: CalendarGrid, selector: "rlb-calendar-grid", inputs: ["view", "currentDate", "events", "intervals", "layout"], outputs: ["event-click", "event-container-click", "event-change"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4083
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: CalendarComponent, isStandalone: true, selector: "rlb-calendar", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, currentDate: { classPropertyName: "currentDate", publicName: "current-date", isSignal: true, isRequired: false, transformFunction: null }, timezone: { classPropertyName: "timezone", publicName: "timezone", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, showToolbar: { classPropertyName: "showToolbar", publicName: "show-toolbar", isSignal: true, isRequired: false, transformFunction: null }, intervals: { classPropertyName: "intervals", publicName: "intervals", isSignal: true, isRequired: false, transformFunction: null }, manageEvents: { classPropertyName: "manageEvents", publicName: "manage-events", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { view: "viewChange", events: "eventsChange", currentDate: "current-dateChange", dateChange: "date-change", viewChange: "view-change", eventClick: "event-click", containerEventClick: "container-event-click" }, ngImport: i0, template: "<div class=\"rlb-calendar\">\n\n @if (showToolbar()) {\n <rlb-calendar-header\n [view]=\"view()\"\n [currentDate]=\"currentDate()\"\n [timezone]=\"timezone()\"\n (viewChange)=\"setView($event)\"\n (dateChange)=\"setDate($event)\"\n >\n </rlb-calendar-header>\n }\n\n @if (loading()) {\n <rlb-progress [infinite]=\"true\" [animated]=\"true\" [height]=\"3\" [showValue]=\"false\">\n </rlb-progress>\n } @else {\n <rlb-calendar-grid\n [events]=\"events()\"\n [intervals]=\"intervals()\"\n [view]=\"view()\"\n [currentDate]=\"currentDate()\"\n [timezone]=\"timezone()\"\n [layout]=\"mergedLayout()\"\n (event-click)=\"onEventClick($event)\"\n (event-container-click)=\"onEventContainerClick($event)\"\n (event-change)=\"onEventChange($event)\"\n >\n </rlb-calendar-grid>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: CalendarHeaderComponent, selector: "rlb-calendar-header", inputs: ["view", "currentDate", "timezone"], outputs: ["dateChange", "viewChange"] }, { kind: "component", type: ProgressComponent, selector: "rlb-progress", inputs: ["max", "min", "value", "height", "animated", "striped", "infinite", "aria-label", "showValue", "color", "text-color"] }, { kind: "component", type: CalendarGrid, selector: "rlb-calendar-grid", inputs: ["view", "currentDate", "events", "intervals", "timezone", "layout"], outputs: ["event-click", "event-container-click", "event-change"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4077
4084
  }
4078
4085
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: CalendarComponent, decorators: [{
4079
4086
  type: Component,
@@ -4081,8 +4088,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
4081
4088
  CalendarHeaderComponent,
4082
4089
  ProgressComponent,
4083
4090
  CalendarGrid,
4084
- ], template: "<div class=\"rlb-calendar\">\n\n @if (showToolbar()) {\n <rlb-calendar-header\n [view]=\"view()\"\n [currentDate]=\"currentDate()\"\n (viewChange)=\"setView($event)\"\n (dateChange)=\"setDate($event)\"\n >\n </rlb-calendar-header>\n }\n\n @if (loading()) {\n <rlb-progress [infinite]=\"true\" [animated]=\"true\" [height]=\"3\" [showValue]=\"false\">\n </rlb-progress>\n } @else {\n <rlb-calendar-grid\n [events]=\"events()\"\n [intervals]=\"intervals()\"\n [view]=\"view()\"\n [currentDate]=\"currentDate()\"\n [layout]=\"mergedLayout()\"\n (event-click)=\"onEventClick($event)\"\n (event-container-click)=\"onEventContainerClick($event)\"\n (event-change)=\"onEventChange($event)\"\n >\n </rlb-calendar-grid>\n }\n</div>\n" }]
4085
- }], ctorParameters: () => [{ type: ModalService }, { type: UniqueIdService }, { type: ToastService }], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: false }] }, { type: i0.Output, args: ["viewChange"] }], events: [{ type: i0.Input, args: [{ isSignal: true, alias: "events", required: false }] }, { type: i0.Output, args: ["eventsChange"] }], currentDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "current-date", required: false }] }, { type: i0.Output, args: ["current-dateChange"] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], showToolbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "show-toolbar", required: false }] }], intervals: [{ type: i0.Input, args: [{ isSignal: true, alias: "intervals", required: false }] }], manageEvents: [{ type: i0.Input, args: [{ isSignal: true, alias: "manage-events", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }], dateChange: [{ type: i0.Output, args: ["date-change"] }], viewChange: [{ type: i0.Output, args: ["view-change"] }], eventClick: [{ type: i0.Output, args: ["event-click"] }], containerEventClick: [{ type: i0.Output, args: ["container-event-click"] }] } });
4091
+ ], template: "<div class=\"rlb-calendar\">\n\n @if (showToolbar()) {\n <rlb-calendar-header\n [view]=\"view()\"\n [currentDate]=\"currentDate()\"\n [timezone]=\"timezone()\"\n (viewChange)=\"setView($event)\"\n (dateChange)=\"setDate($event)\"\n >\n </rlb-calendar-header>\n }\n\n @if (loading()) {\n <rlb-progress [infinite]=\"true\" [animated]=\"true\" [height]=\"3\" [showValue]=\"false\">\n </rlb-progress>\n } @else {\n <rlb-calendar-grid\n [events]=\"events()\"\n [intervals]=\"intervals()\"\n [view]=\"view()\"\n [currentDate]=\"currentDate()\"\n [timezone]=\"timezone()\"\n [layout]=\"mergedLayout()\"\n (event-click)=\"onEventClick($event)\"\n (event-container-click)=\"onEventContainerClick($event)\"\n (event-change)=\"onEventChange($event)\"\n >\n </rlb-calendar-grid>\n }\n</div>\n" }]
4092
+ }], ctorParameters: () => [{ type: ModalService }, { type: UniqueIdService }, { type: ToastService }], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: false }] }, { type: i0.Output, args: ["viewChange"] }], events: [{ type: i0.Input, args: [{ isSignal: true, alias: "events", required: false }] }, { type: i0.Output, args: ["eventsChange"] }], currentDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "current-date", required: false }] }, { type: i0.Output, args: ["current-dateChange"] }], timezone: [{ type: i0.Input, args: [{ isSignal: true, alias: "timezone", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], showToolbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "show-toolbar", required: false }] }], intervals: [{ type: i0.Input, args: [{ isSignal: true, alias: "intervals", required: false }] }], manageEvents: [{ type: i0.Input, args: [{ isSignal: true, alias: "manage-events", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }], dateChange: [{ type: i0.Output, args: ["date-change"] }], viewChange: [{ type: i0.Output, args: ["view-change"] }], eventClick: [{ type: i0.Output, args: ["event-click"] }], containerEventClick: [{ type: i0.Output, args: ["container-event-click"] }] } });
4086
4093
 
4087
4094
  const CALENDAR_COMPONENTS = [
4088
4095
  CalendarComponent,