@progressive-development/pd-calendar 0.9.2 → 1.0.1

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.
Files changed (118) hide show
  1. package/LICENSE +21 -2
  2. package/README.md +32 -57
  3. package/dist/generated/locales/be.d.ts +3 -0
  4. package/dist/generated/locales/be.d.ts.map +1 -1
  5. package/dist/generated/locales/de.d.ts +3 -0
  6. package/dist/generated/locales/de.d.ts.map +1 -1
  7. package/dist/generated/locales/en.d.ts +3 -0
  8. package/dist/generated/locales/en.d.ts.map +1 -1
  9. package/dist/index.d.ts +10 -1
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +16 -0
  12. package/dist/locales/be.js +4 -1
  13. package/dist/locales/de.js +3 -0
  14. package/dist/locales/en.js +4 -1
  15. package/dist/pd-calendar/PdCalendar.d.ts +101 -18
  16. package/dist/pd-calendar/PdCalendar.d.ts.map +1 -1
  17. package/dist/pd-calendar/PdCalendar.js +380 -264
  18. package/dist/pd-calendar/pd-calendar-cell/PdCalendarCell.d.ts +40 -33
  19. package/dist/pd-calendar/pd-calendar-cell/PdCalendarCell.d.ts.map +1 -1
  20. package/dist/pd-calendar/pd-calendar-cell/PdCalendarCell.js +173 -113
  21. package/dist/pd-calendar/pd-calendar-day-events-panel/PdCalendarDayEventsPanel.d.ts +27 -0
  22. package/dist/pd-calendar/pd-calendar-day-events-panel/PdCalendarDayEventsPanel.d.ts.map +1 -0
  23. package/dist/pd-calendar/pd-calendar-day-events-panel/PdCalendarDayEventsPanel.js +160 -0
  24. package/dist/pd-calendar/pd-calendar-day-events-panel/pd-calendar-day-events-panel.d.ts +3 -0
  25. package/dist/pd-calendar/pd-calendar-day-events-panel/pd-calendar-day-events-panel.d.ts.map +1 -0
  26. package/dist/pd-calendar/pd-calendar-day-events-panel/pd-calendar-day-events-panel.js +8 -0
  27. package/dist/pd-calendar/pd-calendar-event-cell/PdCalendarEventCell.d.ts +55 -0
  28. package/dist/pd-calendar/pd-calendar-event-cell/PdCalendarEventCell.d.ts.map +1 -0
  29. package/dist/pd-calendar/pd-calendar-event-cell/PdCalendarEventCell.js +341 -0
  30. package/dist/pd-calendar/pd-calendar-event-cell/pd-calendar-event-cell.d.ts +3 -0
  31. package/dist/pd-calendar/pd-calendar-event-cell/pd-calendar-event-cell.d.ts.map +1 -0
  32. package/dist/pd-calendar/pd-calendar-event-cell/pd-calendar-event-cell.js +8 -0
  33. package/dist/pd-calendar/pd-calendar-event-info-panel/PdCalendarEventInfoPanel.d.ts +29 -0
  34. package/dist/pd-calendar/pd-calendar-event-info-panel/PdCalendarEventInfoPanel.d.ts.map +1 -0
  35. package/dist/pd-calendar/pd-calendar-event-info-panel/PdCalendarEventInfoPanel.js +211 -0
  36. package/dist/pd-calendar/pd-calendar-event-info-panel/pd-calendar-event-info-panel.d.ts +3 -0
  37. package/dist/pd-calendar/pd-calendar-event-info-panel/pd-calendar-event-info-panel.d.ts.map +1 -0
  38. package/dist/pd-calendar/pd-calendar-event-info-panel/pd-calendar-event-info-panel.js +8 -0
  39. package/dist/pd-calendar/pd-calendar-list-cell/PdCalendarListCell.d.ts +28 -0
  40. package/dist/pd-calendar/pd-calendar-list-cell/PdCalendarListCell.d.ts.map +1 -0
  41. package/dist/pd-calendar/pd-calendar-list-cell/PdCalendarListCell.js +252 -0
  42. package/dist/pd-calendar/pd-calendar-list-cell/pd-calendar-list-cell.d.ts +3 -0
  43. package/dist/pd-calendar/pd-calendar-list-cell/pd-calendar-list-cell.d.ts.map +1 -0
  44. package/dist/pd-calendar/pd-calendar-list-cell/pd-calendar-list-cell.js +8 -0
  45. package/dist/pd-calendar/pd-calendar-list-view/PdCalendarListView.d.ts +26 -0
  46. package/dist/pd-calendar/pd-calendar-list-view/PdCalendarListView.d.ts.map +1 -0
  47. package/dist/pd-calendar/pd-calendar-list-view/PdCalendarListView.js +165 -0
  48. package/dist/pd-calendar/pd-calendar-list-view/pd-calendar-list-view.d.ts +3 -0
  49. package/dist/pd-calendar/pd-calendar-list-view/pd-calendar-list-view.d.ts.map +1 -0
  50. package/dist/pd-calendar/pd-calendar-list-view/pd-calendar-list-view.js +8 -0
  51. package/dist/pd-calendar/pd-calendar-month-view/PdCalendarMonthView.d.ts +55 -0
  52. package/dist/pd-calendar/pd-calendar-month-view/PdCalendarMonthView.d.ts.map +1 -0
  53. package/dist/pd-calendar/pd-calendar-month-view/PdCalendarMonthView.js +461 -0
  54. package/dist/pd-calendar/pd-calendar-month-view/pd-calendar-month-view.d.ts +3 -0
  55. package/dist/pd-calendar/pd-calendar-month-view/pd-calendar-month-view.d.ts.map +1 -0
  56. package/dist/pd-calendar/pd-calendar-month-view/pd-calendar-month-view.js +8 -0
  57. package/dist/pd-calendar/pd-calendar-time-grid-view/PdCalendarTimeGridView.d.ts +32 -0
  58. package/dist/pd-calendar/pd-calendar-time-grid-view/PdCalendarTimeGridView.d.ts.map +1 -0
  59. package/dist/pd-calendar/pd-calendar-time-grid-view/PdCalendarTimeGridView.js +468 -0
  60. package/dist/pd-calendar/pd-calendar-time-grid-view/pd-calendar-time-grid-view.d.ts +3 -0
  61. package/dist/pd-calendar/pd-calendar-time-grid-view/pd-calendar-time-grid-view.d.ts.map +1 -0
  62. package/dist/pd-calendar/pd-calendar-time-grid-view/pd-calendar-time-grid-view.js +8 -0
  63. package/dist/pd-calendar/pd-calendar-week-cell/PdCalendarWeekCell.d.ts +31 -0
  64. package/dist/pd-calendar/pd-calendar-week-cell/PdCalendarWeekCell.d.ts.map +1 -0
  65. package/dist/pd-calendar/pd-calendar-week-cell/PdCalendarWeekCell.js +134 -0
  66. package/dist/pd-calendar/pd-calendar-week-cell/pd-calendar-week-cell.d.ts +3 -0
  67. package/dist/pd-calendar/pd-calendar-week-cell/pd-calendar-week-cell.d.ts.map +1 -0
  68. package/dist/pd-calendar/pd-calendar-week-cell/pd-calendar-week-cell.js +8 -0
  69. package/dist/pd-calendar/pd-calendar.stories.d.ts +79 -19
  70. package/dist/pd-calendar/pd-calendar.stories.d.ts.map +1 -1
  71. package/dist/pd-calendar/pd-year-popup/PdYearPopup.d.ts +22 -11
  72. package/dist/pd-calendar/pd-year-popup/PdYearPopup.d.ts.map +1 -1
  73. package/dist/pd-calendar/pd-year-popup/PdYearPopup.js +152 -34
  74. package/dist/pd-datepicker/PdDatepicker.d.ts +76 -7
  75. package/dist/pd-datepicker/PdDatepicker.d.ts.map +1 -1
  76. package/dist/pd-datepicker/PdDatepicker.js +257 -50
  77. package/dist/pd-datepicker/pd-date-picker.stories.d.ts +78 -20
  78. package/dist/pd-datepicker/pd-date-picker.stories.d.ts.map +1 -1
  79. package/dist/pd-slot-picker/PdSlotPicker.d.ts +102 -0
  80. package/dist/pd-slot-picker/PdSlotPicker.d.ts.map +1 -0
  81. package/dist/pd-slot-picker/PdSlotPicker.js +339 -0
  82. package/dist/pd-slot-picker/pd-slot-cell/PdSlotCell.d.ts +35 -0
  83. package/dist/pd-slot-picker/pd-slot-cell/PdSlotCell.d.ts.map +1 -0
  84. package/dist/pd-slot-picker/pd-slot-cell/PdSlotCell.js +188 -0
  85. package/dist/pd-slot-picker/pd-slot-cell/pd-slot-cell.d.ts +3 -0
  86. package/dist/pd-slot-picker/pd-slot-cell/pd-slot-cell.d.ts.map +1 -0
  87. package/dist/pd-slot-picker/pd-slot-cell/pd-slot-cell.js +8 -0
  88. package/dist/pd-slot-picker/pd-slot-picker.d.ts +3 -0
  89. package/dist/pd-slot-picker/pd-slot-picker.d.ts.map +1 -0
  90. package/dist/pd-slot-picker/pd-slot-picker.stories.d.ts +67 -0
  91. package/dist/pd-slot-picker/pd-slot-picker.stories.d.ts.map +1 -0
  92. package/dist/pd-slot-picker.d.ts +2 -0
  93. package/dist/pd-slot-picker.js +8 -0
  94. package/dist/shared/PdBaseCell.d.ts +68 -0
  95. package/dist/shared/PdBaseCell.d.ts.map +1 -0
  96. package/dist/shared/PdBaseCell.js +120 -0
  97. package/dist/shared/PdBaseView.d.ts +22 -0
  98. package/dist/shared/PdBaseView.d.ts.map +1 -0
  99. package/dist/shared/PdBaseView.js +46 -0
  100. package/dist/shared/PdCalendarPanelBase.d.ts +34 -0
  101. package/dist/shared/PdCalendarPanelBase.d.ts.map +1 -0
  102. package/dist/shared/PdCalendarPanelBase.js +169 -0
  103. package/dist/shared/calendar-button-bar/calendar-button-bar.d.ts +41 -0
  104. package/dist/shared/calendar-button-bar/calendar-button-bar.d.ts.map +1 -0
  105. package/dist/shared/calendar-button-bar/calendar-button-bar.js +435 -0
  106. package/dist/shared/calendar-locales.d.ts +9 -0
  107. package/dist/shared/calendar-locales.d.ts.map +1 -0
  108. package/dist/shared/calendar-locales.js +30 -0
  109. package/dist/shared/calendar-utils.d.ts +34 -0
  110. package/dist/shared/calendar-utils.d.ts.map +1 -0
  111. package/dist/shared/calendar-utils.js +99 -0
  112. package/dist/shared/calendar-utils.test.d.ts +2 -0
  113. package/dist/shared/calendar-utils.test.d.ts.map +1 -0
  114. package/dist/types.d.ts +102 -1
  115. package/dist/types.d.ts.map +1 -1
  116. package/package.json +10 -5
  117. package/dist/pd-calendar/pd-calendar-cell/pd-calendar-cell.stories.d.ts +0 -15
  118. package/dist/pd-calendar/pd-calendar-cell/pd-calendar-cell.stories.d.ts.map +0 -1
@@ -1,11 +1,14 @@
1
- import { css, LitElement, html } from 'lit';
1
+ import { css, LitElement, nothing, html } from 'lit';
2
2
  import { property, state } from 'lit/decorators.js';
3
- import { msg, localized } from '@lit/localize';
4
- import { format } from 'fecha';
3
+ import { localized } from '@lit/localize';
5
4
  import '@progressive-development/pd-icon/pd-icon';
6
- import './pd-year-popup/pd-year-popup.js';
7
- import './pd-calendar-cell/pd-calendar-cell.js';
8
- import { PdYearPopup } from './pd-year-popup/PdYearPopup.js';
5
+ import { LOCALES } from '../shared/calendar-locales.js';
6
+ import './pd-calendar-month-view/pd-calendar-month-view.js';
7
+ import './pd-calendar-list-view/pd-calendar-list-view.js';
8
+ import './pd-calendar-time-grid-view/pd-calendar-time-grid-view.js';
9
+ import './pd-calendar-event-info-panel/pd-calendar-event-info-panel.js';
10
+ import './pd-calendar-day-events-panel/pd-calendar-day-events-panel.js';
11
+ import '../shared/calendar-button-bar/calendar-button-bar.js';
9
12
 
10
13
  var __defProp = Object.defineProperty;
11
14
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -17,41 +20,6 @@ var __decorateClass = (decorators, target, key, kind) => {
17
20
  if (kind && result) __defProp(target, key, result);
18
21
  return result;
19
22
  };
20
- const TOUCH_MIN_MOVE = 70;
21
- const loadLocales = () => ({
22
- monthNames: [
23
- msg("Januar", { id: "pd.datepicker.month.jan" }),
24
- msg("Februar", { id: "pd.datepicker.month.feb" }),
25
- msg("März", { id: "pd.datepicker.month.mar" }),
26
- msg("April", { id: "pd.datepicker.month.apr" }),
27
- msg("Mai", { id: "pd.datepicker.month.may" }),
28
- msg("Juni", { id: "pd.datepicker.month.jun" }),
29
- msg("Juli", { id: "pd.datepicker.month.jul" }),
30
- msg("August", { id: "pd.datepicker.month.aug" }),
31
- msg("September", { id: "pd.datepicker.month.sep" }),
32
- msg("Oktober", { id: "pd.datepicker.month.oct" }),
33
- msg("November", { id: "pd.datepicker.month.nov" }),
34
- msg("Dezember", { id: "pd.datepicker.month.dec" })
35
- ],
36
- weekdaysShort: [
37
- msg("Mo", { id: "pd.datepicker.shortday.mon" }),
38
- msg("Di", { id: "pd.datepicker.shortday.tue" }),
39
- msg("Mi", { id: "pd.datepicker.shortday.wed" }),
40
- msg("Do", { id: "pd.datepicker.shortday.thi" }),
41
- msg("Fr", { id: "pd.datepicker.shortday.fri" }),
42
- msg("Sa", { id: "pd.datepicker.shortday.sat" }),
43
- msg("So", { id: "pd.datepicker.shortday.sun" })
44
- ]
45
- });
46
- const LOCALES = loadLocales();
47
- const VIEW_MONTH = 2;
48
- function isToday(date) {
49
- const today = /* @__PURE__ */ new Date();
50
- return !!date && date.getDate() === today.getDate() && date.getMonth() === today.getMonth() && date.getFullYear() === today.getFullYear();
51
- }
52
- function isSelected(date1, date2) {
53
- return !!date1 && !!date2 && date1.getDate() === date2.getDate() && date1.getMonth() === date2.getMonth() && date1.getFullYear() === date2.getFullYear();
54
- }
55
23
  let PdCalendar = class extends LitElement {
56
24
  constructor() {
57
25
  super(...arguments);
@@ -65,120 +33,225 @@ let PdCalendar = class extends LitElement {
65
33
  this.nextMonthConstraint = -1;
66
34
  this.data = {};
67
35
  this.numberClass = "top-left";
68
- this._viewType = VIEW_MONTH;
36
+ this.cellType = "simple";
37
+ this._infoPanelDateKey = "";
38
+ this._dayEventsPanelDateKey = "";
39
+ this._currentViewType = "dayGrid";
69
40
  this._currentDate = /* @__PURE__ */ new Date();
70
- this._wheelDelta = 0;
71
41
  this._monthName = "";
72
42
  this._year = 0;
73
43
  this._numberOfDays = 0;
74
- this._daysFromPreviousMonth = [];
75
44
  this._currentMonthNavNr = 0;
76
45
  }
77
46
  connectedCallback() {
78
47
  super.connectedCallback();
79
- this._initFromDate(this.refDate ?? /* @__PURE__ */ new Date());
48
+ const initDate = this.refDate ?? /* @__PURE__ */ new Date();
49
+ this._initFromDate(initDate);
50
+ this._currentWeekStart = this._getMonday(initDate);
80
51
  }
81
52
  update(changedProperties) {
82
53
  if (changedProperties.has("refDate") && this.refDate) {
83
54
  this._initFromDate(this.refDate);
55
+ this._currentWeekStart = this._getMonday(this.refDate);
56
+ }
57
+ if (changedProperties.has("availableViewTypes") && this.availableViewTypes) {
58
+ const defaultIndex = this.availableViewTypes.default ?? 0;
59
+ const defaultViewType = this.availableViewTypes.viewTypes[defaultIndex];
60
+ if (defaultViewType) {
61
+ this._currentViewType = defaultViewType;
62
+ }
84
63
  }
85
64
  super.update(changedProperties);
86
65
  }
87
66
  render() {
67
+ const hideButtonBar = !this.availableViewTypes || this.availableViewTypes.viewTypes.length <= 1;
68
+ const isRangeMode = this._currentViewType === "list" && !!this.listRange;
69
+ const isWeekView = this._currentViewType === "timeGrid";
70
+ const title = isRangeMode ? this._formatRangeTitle() : isWeekView ? this._formatWeekTitle() : this._monthName;
71
+ const year = isRangeMode || isWeekView ? 0 : this._year;
72
+ const hidePrev = isWeekView ? false : !this._checkPrevMonthConstraint();
73
+ const hideNext = isWeekView ? false : !this._checkNextMonthConstraint();
88
74
  return html`
89
- ${this.renderMonthCalendar()}
90
- <slot name="calFooter"></slot>
91
- `;
92
- }
93
- renderMonthCalendar() {
94
- const sizeClass = this._numberOfDays >= 31 && this._daysFromPreviousMonth.length >= 5 ? "max" : "normal";
95
- const days = Array.from({ length: this._numberOfDays }, (_, i) => {
96
- const day = i + 1;
97
- const date = new Date(this._year, this._currentDate.getMonth(), day);
98
- if (this.hideWeekend && [0, 6].includes(date.getDay())) return null;
99
- const key = format(date, "YYYY-MM-DD");
100
- const cellData = this.data ? this.data[key]?.[0] : void 0;
101
- return html`
102
- <pd-calendar-cell
103
- key=${key}
104
- .dayNumber=${day}
105
- .weekDayNumber=${date.getDay()}
106
- .infoTxt=${cellData?.info || ""}
107
- ?selectEnabled=${this.selectableDates || !!cellData?.info}
108
- ?special=${cellData?.special ?? false}
109
- .numberClass=${this.numberClass}
110
- ?today=${this.selectableDates && isToday(date)}
111
- ?selected=${this.showSelection && isSelected(this.refDate, date)}
112
- ></pd-calendar-cell>
113
- `;
114
- });
115
- return html`
116
- <div class="layout-container">
75
+ <div
76
+ class="layout-container"
77
+ @select-event="${this._handleSelectEvent}"
78
+ @show-day-events="${this._handleShowDayEvents}"
79
+ >
117
80
  <div class="header">
118
81
  <div class="header-main">
119
- <div class="icon-container">
120
- <pd-icon
121
- class="arrow"
122
- icon="previousArrow"
123
- activeIcon
124
- @click=${this._previousMonth}
125
- ></pd-icon>
126
- <pd-icon
127
- class="arrow"
128
- icon="nextArrow"
129
- activeIcon
130
- @click=${this._nextMonth}
131
- ></pd-icon>
132
- </div>
133
- <div id="titleContentId" class="content-title">
134
- ${this._monthName}
135
- ${this.withYearPopup.length > 0 ? html`<span
136
- class="year-popup-link"
137
- @click=${this._openYearPopup}
138
- >${this._year}</span
139
- >` : this._year}
140
- </div>
82
+ <calendar-button-bar
83
+ ?hideButtonBar="${hideButtonBar}"
84
+ year="${year}"
85
+ currentTitle="${title}"
86
+ .currentDate="${this._currentDate}"
87
+ .withYearPopup="${isRangeMode || isWeekView ? [] : this.withYearPopup}"
88
+ .availableViewTypes="${this.availableViewTypes ?? {
89
+ viewTypes: ["dayGrid"],
90
+ default: 0
91
+ }}"
92
+ .availablePeriods="${{
93
+ periods: ["Month"],
94
+ default: 0
95
+ }}"
96
+ ?hideNavigation="${isRangeMode}"
97
+ ?hidePrev="${hidePrev}"
98
+ ?hideNext="${hideNext}"
99
+ @pd-calendar-navigation="${this._handleNavigationEvent}"
100
+ @pd-calendar-change-view="${this._handleViewChange}"
101
+ ></calendar-button-bar>
141
102
  </div>
142
103
  </div>
143
104
 
144
- <div
145
- class="content grid-container ${sizeClass}"
146
- @wheel=${this._wheelEvent}
147
- @touchstart=${this._touchStartEvent}
148
- @touchend=${this._touchEndEvent}
149
- >
150
- ${this._getWeekDays().map(
151
- (day) => html`<div class="title-week-day">${day}</div>`
152
- )}
153
- ${this._daysFromPreviousMonth.map(
154
- () => html`<div class="cell cell-empty"></div>`
155
- )}
156
- ${days}
157
- </div>
105
+ ${this._currentViewType === "list" ? html`
106
+ <pd-calendar-list-view
107
+ .data="${this.data}"
108
+ .config="${this.config}"
109
+ .refDate="${this.refDate}"
110
+ .currentDate="${this._currentDate}"
111
+ .listRange="${this.listRange}"
112
+ ?showSelection="${this.showSelection}"
113
+ ></pd-calendar-list-view>
114
+ ` : this._currentViewType === "timeGrid" ? html`
115
+ <pd-calendar-time-grid-view
116
+ .data="${this.data}"
117
+ .config="${this.config}"
118
+ .currentWeekStart="${this._currentWeekStart}"
119
+ .weekViewConfig="${this.weekViewConfig}"
120
+ ?hideWeekend="${this.hideWeekend}"
121
+ ></pd-calendar-time-grid-view>
122
+ ` : html`
123
+ <pd-calendar-month-view
124
+ .data="${this.data}"
125
+ .config="${this.config}"
126
+ .refDate="${this.refDate}"
127
+ .currentDate="${this._currentDate}"
128
+ ?hideWeekend="${this.hideWeekend}"
129
+ ?selectableDates="${this.selectableDates}"
130
+ ?showSelection="${this.showSelection}"
131
+ .numberClass="${this.numberClass}"
132
+ .cellType="${this.cellType}"
133
+ ?withWheelNavigation="${this.withWheelNavigation}"
134
+ ?withTouchNavigation="${this.withTouchNavigation}"
135
+ @pd-navigate="${this._handleViewNavigate}"
136
+ ></pd-calendar-month-view>
137
+ `}
138
+ ${this._infoPanelEntry ? html`<pd-calendar-event-info-panel
139
+ .entry="${this._infoPanelEntry}"
140
+ .dateKey="${this._infoPanelDateKey}"
141
+ .actions="${this.eventActions ?? {
142
+ detail: true,
143
+ edit: true,
144
+ delete: true
145
+ }}"
146
+ .config="${this.config}"
147
+ .anchorRect="${this._infoPanelAnchorRect}"
148
+ @close-panel="${this._closeInfoPanel}"
149
+ @event-action="${this._reDispatchEventAction}"
150
+ ></pd-calendar-event-info-panel>` : nothing}
151
+ ${this._dayEventsPanelEntries ? html`<pd-calendar-day-events-panel
152
+ .entries="${this._dayEventsPanelEntries}"
153
+ .dateKey="${this._dayEventsPanelDateKey}"
154
+ .config="${this.config}"
155
+ .anchorRect="${this._dayEventsPanelAnchorRect}"
156
+ @close-panel="${this._closeDayEventsPanel}"
157
+ @select-event="${this._handleDayEventsSelectEvent}"
158
+ ></pd-calendar-day-events-panel>` : nothing}
158
159
  </div>
160
+ <slot name="calFooter"></slot>
159
161
  `;
160
162
  }
161
- _openYearPopup() {
162
- const popup = new PdYearPopup();
163
- popup.yearSelection = this.withYearPopup;
164
- this.shadowRoot?.getElementById("titleContentId")?.appendChild(popup);
165
- popup.addEventListener("abort-year-selection", () => {
166
- this.shadowRoot?.getElementById("titleContentId")?.removeChild(popup);
167
- });
168
- popup.addEventListener("change-year-selection", (e) => {
169
- const year = e.detail.year;
170
- const newDate = new Date(this._currentDate);
171
- newDate.setFullYear(year);
172
- this.dispatchEvent(
173
- new CustomEvent("change-month", { detail: { newDate } })
174
- );
175
- this._initFromDate(newDate);
176
- this.shadowRoot?.getElementById("titleContentId")?.removeChild(popup);
177
- });
163
+ // ===========================================================================
164
+ // Event Handlers
165
+ // ===========================================================================
166
+ /** Handles navigation from the month view (wheel/touch/keyboard). */
167
+ _handleViewNavigate(e) {
168
+ if (e.detail.direction === "next") {
169
+ this._nextMonth();
170
+ } else {
171
+ this._previousMonth();
172
+ }
173
+ e.stopPropagation();
174
+ }
175
+ /** Handles view type change from the button bar. */
176
+ _handleViewChange(e) {
177
+ const viewType = e.detail.viewType;
178
+ if (viewType) {
179
+ this._currentViewType = viewType;
180
+ }
181
+ e.stopPropagation();
182
+ }
183
+ _handleNavigationEvent(e) {
184
+ if (this._currentViewType === "timeGrid") {
185
+ if (e.detail.previous) {
186
+ this._previousWeek();
187
+ }
188
+ if (e.detail.next) {
189
+ this._nextWeek();
190
+ }
191
+ } else {
192
+ if (e.detail.previous) {
193
+ this._previousMonth();
194
+ }
195
+ if (e.detail.next) {
196
+ this._nextMonth();
197
+ }
198
+ if (e.detail.newDate) {
199
+ this._initFromDate(e.detail.newDate);
200
+ }
201
+ }
202
+ e.stopPropagation();
203
+ }
204
+ // ===========================================================================
205
+ // Event Info Panel
206
+ // ===========================================================================
207
+ /** Opens the event info panel. Closes the day-events panel if open. */
208
+ _handleSelectEvent(e) {
209
+ const { dateKey, entry, anchorRect } = e.detail;
210
+ this._closeDayEventsPanel();
211
+ this._infoPanelEntry = entry;
212
+ this._infoPanelDateKey = dateKey;
213
+ this._infoPanelAnchorRect = anchorRect;
214
+ }
215
+ /** Opens the day-events panel. Closes the event info panel if open. */
216
+ _handleShowDayEvents(e) {
217
+ const { dateKey, entries, anchorRect } = e.detail;
218
+ this._closeInfoPanel();
219
+ this._dayEventsPanelEntries = entries;
220
+ this._dayEventsPanelDateKey = dateKey;
221
+ this._dayEventsPanelAnchorRect = anchorRect;
222
+ }
223
+ /** Handles select-event from within the day-events panel. */
224
+ _handleDayEventsSelectEvent(e) {
225
+ e.stopPropagation();
226
+ const { dateKey, entry, anchorRect } = e.detail;
227
+ this._closeDayEventsPanel();
228
+ this._infoPanelEntry = entry;
229
+ this._infoPanelDateKey = dateKey;
230
+ this._infoPanelAnchorRect = anchorRect;
178
231
  }
179
- _getWeekDays() {
180
- return this.hideWeekend ? LOCALES.weekdaysShort.slice(0, 5) : LOCALES.weekdaysShort;
232
+ _closeInfoPanel() {
233
+ this._infoPanelEntry = void 0;
234
+ this._infoPanelDateKey = "";
235
+ this._infoPanelAnchorRect = void 0;
181
236
  }
237
+ _closeDayEventsPanel() {
238
+ this._dayEventsPanelEntries = void 0;
239
+ this._dayEventsPanelDateKey = "";
240
+ this._dayEventsPanelAnchorRect = void 0;
241
+ }
242
+ /** Re-dispatches event-action from the info panel. */
243
+ _reDispatchEventAction(e) {
244
+ this.dispatchEvent(
245
+ new CustomEvent("event-action", {
246
+ detail: e.detail,
247
+ bubbles: true,
248
+ composed: true
249
+ })
250
+ );
251
+ }
252
+ // ===========================================================================
253
+ // Month Navigation
254
+ // ===========================================================================
182
255
  _nextMonth() {
183
256
  if (this._checkNextMonthConstraint()) {
184
257
  const next = new Date(
@@ -188,7 +261,9 @@ let PdCalendar = class extends LitElement {
188
261
  );
189
262
  this.dispatchEvent(
190
263
  new CustomEvent("change-month", {
191
- detail: { newDate: next, next: true }
264
+ detail: { newDate: next, next: true },
265
+ bubbles: true,
266
+ composed: true
192
267
  })
193
268
  );
194
269
  this._currentMonthNavNr += 1;
@@ -204,105 +279,157 @@ let PdCalendar = class extends LitElement {
204
279
  );
205
280
  this.dispatchEvent(
206
281
  new CustomEvent("change-month", {
207
- detail: { newDate: prev, prev: true }
282
+ detail: { newDate: prev, prev: true },
283
+ bubbles: true,
284
+ composed: true
208
285
  })
209
286
  );
210
287
  this._currentMonthNavNr -= 1;
211
288
  this._initFromDate(prev);
212
289
  }
213
290
  }
214
- _wheelEvent(e) {
215
- if (this.withWheelNavigation) {
216
- this._wheelDelta += e.deltaY;
217
- if (this._wheelDelta > 360) {
218
- this._wheelDelta = 0;
219
- this._nextMonth();
220
- } else if (this._wheelDelta < -360) {
221
- this._wheelDelta = 0;
222
- this._previousMonth();
223
- }
224
- }
225
- e.preventDefault();
226
- e.stopPropagation();
291
+ _checkNextMonthConstraint() {
292
+ return this.nextMonthConstraint === -1 || this.nextMonthConstraint > this._currentMonthNavNr;
227
293
  }
228
- _touchStartEvent(e) {
229
- if (this.withTouchNavigation) {
230
- this._wheelDelta = e.changedTouches[0].screenX;
231
- }
232
- e.stopPropagation();
294
+ _checkPrevMonthConstraint() {
295
+ return this.prevMonthConstraint === -1 || this._currentMonthNavNr > 0 || this.prevMonthConstraint > this._currentMonthNavNr * -1;
233
296
  }
234
- _touchEndEvent(e) {
235
- if (this.withTouchNavigation) {
236
- const diff = this._wheelDelta - e.changedTouches[0].screenX;
237
- if (diff < -TOUCH_MIN_MOVE) {
238
- this._nextMonth();
239
- } else if (diff > TOUCH_MIN_MOVE) {
240
- this._previousMonth();
241
- }
242
- }
243
- e.stopPropagation();
297
+ // ===========================================================================
298
+ // Week Navigation
299
+ // ===========================================================================
300
+ _nextWeek() {
301
+ if (!this._currentWeekStart) return;
302
+ const next = new Date(this._currentWeekStart);
303
+ next.setDate(next.getDate() + 7);
304
+ this._currentWeekStart = next;
244
305
  }
306
+ _previousWeek() {
307
+ if (!this._currentWeekStart) return;
308
+ const prev = new Date(this._currentWeekStart);
309
+ prev.setDate(prev.getDate() - 7);
310
+ this._currentWeekStart = prev;
311
+ }
312
+ // ===========================================================================
313
+ // Helpers
314
+ // ===========================================================================
245
315
  _initFromDate(date) {
246
- this._monthName = date.toLocaleString("default", { month: "long" });
316
+ this._monthName = LOCALES.monthNames[date.getMonth()];
247
317
  this._year = date.getFullYear();
248
318
  this._currentDate = date;
249
- this._daysFromPreviousMonth = PdCalendar._getPreviousMonthDays(date);
250
- const lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0);
251
- this._numberOfDays = lastDay.getDate();
319
+ this._numberOfDays = new Date(
320
+ date.getFullYear(),
321
+ date.getMonth() + 1,
322
+ 0
323
+ ).getDate();
252
324
  }
253
- static _getPreviousMonthDays(date) {
254
- const start = new Date(date.getFullYear(), date.getMonth(), 1);
255
- const missing = start.getDay() > 0 ? Math.abs(1 - start.getDay()) : 6;
256
- return Array.from({ length: missing }, (_, i) => {
257
- const d = new Date(start);
258
- d.setDate(start.getDate() - (missing - i));
259
- return d;
260
- });
325
+ /** Returns the Monday of the week that contains `date`. */
326
+ _getMonday(date) {
327
+ const d = new Date(date);
328
+ const day = d.getDay();
329
+ const diff = day === 0 ? -6 : 1 - day;
330
+ d.setDate(d.getDate() + diff);
331
+ d.setHours(0, 0, 0, 0);
332
+ return d;
261
333
  }
262
- _checkNextMonthConstraint() {
263
- return this.nextMonthConstraint === -1 || this.nextMonthConstraint > this._currentMonthNavNr;
334
+ // ===========================================================================
335
+ // Title Formatting
336
+ // ===========================================================================
337
+ /**
338
+ * Formats the range title based on the listRange dates.
339
+ */
340
+ _formatRangeTitle() {
341
+ if (!this.listRange) return "";
342
+ const start = this._parseDate(this.listRange.start);
343
+ const end = this._parseDate(this.listRange.end);
344
+ const startDay = start.getDate().toString().padStart(2, "0");
345
+ const startMonth = (start.getMonth() + 1).toString().padStart(2, "0");
346
+ const startYear = start.getFullYear().toString().slice(-2);
347
+ const endDay = end.getDate().toString().padStart(2, "0");
348
+ const endMonth = (end.getMonth() + 1).toString().padStart(2, "0");
349
+ const endYear = end.getFullYear().toString().slice(-2);
350
+ const sameYear = start.getFullYear() === end.getFullYear();
351
+ const sameMonth = sameYear && start.getMonth() === end.getMonth();
352
+ if (sameMonth) {
353
+ return `${startDay}-${endDay}.${startMonth}.${startYear}`;
354
+ } else if (sameYear) {
355
+ return `${startDay}.${startMonth} - ${endDay}.${endMonth}.${endYear}`;
356
+ } else {
357
+ return `${startDay}.${startMonth}.${startYear} - ${endDay}.${endMonth}.${endYear}`;
358
+ }
264
359
  }
265
- _checkPrevMonthConstraint() {
266
- return this.prevMonthConstraint === -1 || this._currentMonthNavNr > 0 || this.prevMonthConstraint > this._currentMonthNavNr * -1;
360
+ /**
361
+ * Formats the week title, e.g. "10. - 16. Feb" or "28. Jan - 03. Feb".
362
+ */
363
+ _formatWeekTitle() {
364
+ if (!this._currentWeekStart) return "";
365
+ const visibleDays = this._getVisibleDays();
366
+ const firstDay = this._getDateForDayIndex(visibleDays[0]);
367
+ const lastDay = this._getDateForDayIndex(
368
+ visibleDays[visibleDays.length - 1]
369
+ );
370
+ if (!firstDay || !lastDay) return "";
371
+ const months = LOCALES.monthNames;
372
+ const fDay = firstDay.getDate().toString().padStart(2, "0");
373
+ const lDay = lastDay.getDate().toString().padStart(2, "0");
374
+ const fMonthShort = months[firstDay.getMonth()].slice(0, 3);
375
+ const lMonthShort = months[lastDay.getMonth()].slice(0, 3);
376
+ const lYear = lastDay.getFullYear();
377
+ if (firstDay.getMonth() === lastDay.getMonth() && firstDay.getFullYear() === lastDay.getFullYear()) {
378
+ return `${fDay}. - ${lDay}. ${fMonthShort} ${lYear}`;
379
+ }
380
+ if (firstDay.getFullYear() === lastDay.getFullYear()) {
381
+ return `${fDay}. ${fMonthShort} - ${lDay}. ${lMonthShort} ${lYear}`;
382
+ }
383
+ return `${fDay}. ${fMonthShort} ${firstDay.getFullYear()} - ${lDay}. ${lMonthShort} ${lYear}`;
384
+ }
385
+ _parseDate(value) {
386
+ if (value instanceof Date) return value;
387
+ const [year, month, day] = value.split("-").map(Number);
388
+ return new Date(year, month - 1, day);
389
+ }
390
+ /** Returns effective visible day indices for week title calculation. */
391
+ _getVisibleDays() {
392
+ if (this.weekViewConfig?.visibleDays) {
393
+ return this.weekViewConfig.visibleDays;
394
+ }
395
+ if (this.hideWeekend) {
396
+ return [0, 1, 2, 3, 4];
397
+ }
398
+ return [0, 1, 2, 3, 4, 5, 6];
399
+ }
400
+ /** Calculates the actual Date for a given monday-based day index. */
401
+ _getDateForDayIndex(dayIndex) {
402
+ if (!this._currentWeekStart) return void 0;
403
+ const d = new Date(this._currentWeekStart);
404
+ d.setDate(d.getDate() + dayIndex);
405
+ return d;
267
406
  }
268
407
  };
269
408
  PdCalendar.styles = [
270
409
  css`
271
410
  :host {
272
- --my-cell-height: var(--pd-calendar-cell-height, 70px);
273
-
274
411
  display: block;
275
- /*padding: 8px;
276
- width: 100vw;
277
- height: 100vh;*/
278
- }
279
-
280
- :host([hideWeekend]) .grid-container {
281
- grid-template-columns: repeat(5, minmax(0, 1fr));
412
+ container-type: inline-size;
413
+ font-family: var(--pd-default-font-content-family);
414
+ width: var(--pd-calendar-width, 100%);
415
+ min-width: var(--pd-calendar-min-width, 310px);
282
416
  }
283
417
 
284
- /* Layout Grid for the Calendar Component => Not really needed at the moment, more a test */
285
418
  .layout-container {
286
- width: var(--pd-calendar-width, 100%);
419
+ width: 100%;
287
420
  min-width: 220px;
288
421
  height: 100%;
289
- display: grid;
290
- grid-template-columns: 1fr 1fr 1fr;
291
- grid-template-rows: 40px auto;
292
- gap: 1px;
293
- grid-template-areas:
294
- "header header header"
295
- "content content content";
422
+ display: flex;
423
+ flex-direction: column;
424
+ gap: var(--pd-spacing-sm);
425
+ background-color: var(--pd-default-bg-col);
426
+ border-radius: var(--pd-radius-lg);
427
+ padding: var(--pd-calendar-padding, var(--pd-spacing-sm));
296
428
  }
297
429
 
298
- /* Grid Area positions for layout container above */
299
430
  .header {
300
- grid-area: header;
301
431
  position: relative;
302
432
  font-family: var(--pd-default-font-title-family);
303
- color: var(--pd-default-font-title-col);
304
- display: flex;
305
- justify-content: left;
306
433
  }
307
434
 
308
435
  .header-main {
@@ -312,76 +439,29 @@ PdCalendar.styles = [
312
439
  width: 100%;
313
440
  }
314
441
 
315
- .content {
316
- grid-area: content;
317
- }
318
- .footer {
319
- grid-area: footer;
320
- }
321
-
322
- /* Grid definition for calendar day items */
323
- .grid-container {
324
- position: relative;
325
- display: grid;
326
- grid-template-columns: repeat(7, minmax(0, 1fr));
327
- gap: 3px;
328
- }
329
-
330
- .grid-container.max {
331
- grid-template-rows: minmax(10px, 30px) repeat(
332
- 6,
333
- minmax(var(--my-cell-height), 1fr)
334
- );
335
- }
336
-
337
- .grid-container.normal {
338
- grid-template-rows: minmax(10px, 30px) repeat(
339
- 5,
340
- minmax(var(--my-cell-height), 1fr)
341
- );
342
- }
343
-
344
- .title-week-day {
345
- display: flex;
346
- align-items: center;
347
- justify-content: center;
348
- background-color: var(
349
- --pd-calendar-week-title-bg-col,
350
- var(--pd-default-dark-col)
351
- );
352
- font-size: var(--pd-calendar-weekday-title-font-size, 1em);
353
- font-weight: bold;
354
- color: var(--pd-calendar-week-title-font-col, var(--pd-default-bg-col));
355
- font-family: var(--pd-default-font-title-family);
356
- }
357
-
358
- .content-title {
359
- position: relative;
360
- font-size: var(--pd-calendar-title-font-size, 1.2em);
361
- font-weight: bold;
362
- }
363
-
364
- .icon-container {
365
- display: flex;
366
- align-items: center;
367
- justify-content: center;
368
- gap: 5px;
442
+ .header-main calendar-button-bar {
443
+ width: 100%;
444
+ --pd-cbar-title-align: right;
445
+ --pd-cbar-title-col: var(--pd-default-font-title-col);
446
+ --pd-cbar-title-size: 1.2em;
447
+ --pd-cbar-title-weight: 600;
369
448
  }
370
449
 
371
- .arrow {
372
- cursor: pointer;
373
- --pd-icon-size: var(--pd-calendar-title-icon-size, 1.2em);
374
- --pd-icon-bg-col-hover: lightgrey;
375
- }
450
+ @container (max-width: 500px) {
451
+ .header-main calendar-button-bar {
452
+ --pd-cbar-title-button-size: 36px;
453
+ }
376
454
 
377
- .year-popup-link {
378
- color: var(--pd-default-font-link-col);
379
- text-decoration: underline;
455
+ .layout-container {
456
+ padding: var(--pd-spacing-xs, 0.25rem);
457
+ gap: var(--pd-spacing-xs, 0.25rem);
458
+ }
380
459
  }
381
460
 
382
- .year-popup-link:hover {
383
- cursor: pointer;
384
- color: var(--pd-default-hover-col);
461
+ @container (max-width: 300px) {
462
+ .layout-container {
463
+ padding: 2px;
464
+ }
385
465
  }
386
466
  `
387
467
  ];
@@ -418,15 +498,51 @@ __decorateClass([
418
498
  __decorateClass([
419
499
  property({ type: String })
420
500
  ], PdCalendar.prototype, "numberClass", 2);
501
+ __decorateClass([
502
+ property({ type: Object })
503
+ ], PdCalendar.prototype, "availableViewTypes", 2);
504
+ __decorateClass([
505
+ property({ type: Object })
506
+ ], PdCalendar.prototype, "config", 2);
507
+ __decorateClass([
508
+ property({ type: Object })
509
+ ], PdCalendar.prototype, "listRange", 2);
510
+ __decorateClass([
511
+ property({ type: Object })
512
+ ], PdCalendar.prototype, "weekViewConfig", 2);
513
+ __decorateClass([
514
+ property({ type: String })
515
+ ], PdCalendar.prototype, "cellType", 2);
516
+ __decorateClass([
517
+ property({ type: Object })
518
+ ], PdCalendar.prototype, "eventActions", 2);
519
+ __decorateClass([
520
+ state()
521
+ ], PdCalendar.prototype, "_infoPanelEntry", 2);
522
+ __decorateClass([
523
+ state()
524
+ ], PdCalendar.prototype, "_infoPanelDateKey", 2);
525
+ __decorateClass([
526
+ state()
527
+ ], PdCalendar.prototype, "_infoPanelAnchorRect", 2);
528
+ __decorateClass([
529
+ state()
530
+ ], PdCalendar.prototype, "_dayEventsPanelEntries", 2);
531
+ __decorateClass([
532
+ state()
533
+ ], PdCalendar.prototype, "_dayEventsPanelDateKey", 2);
534
+ __decorateClass([
535
+ state()
536
+ ], PdCalendar.prototype, "_dayEventsPanelAnchorRect", 2);
421
537
  __decorateClass([
422
538
  state()
423
- ], PdCalendar.prototype, "_viewType", 2);
539
+ ], PdCalendar.prototype, "_currentViewType", 2);
424
540
  __decorateClass([
425
541
  state()
426
542
  ], PdCalendar.prototype, "_currentDate", 2);
427
543
  __decorateClass([
428
544
  state()
429
- ], PdCalendar.prototype, "_wheelDelta", 2);
545
+ ], PdCalendar.prototype, "_currentWeekStart", 2);
430
546
  PdCalendar = __decorateClass([
431
547
  localized()
432
548
  ], PdCalendar);