@progressive-development/pd-calendar 0.9.2 → 1.0.0
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.
- package/LICENSE +21 -2
- package/README.md +32 -57
- package/dist/generated/locales/be.d.ts +3 -0
- package/dist/generated/locales/be.d.ts.map +1 -1
- package/dist/generated/locales/de.d.ts +3 -0
- package/dist/generated/locales/de.d.ts.map +1 -1
- package/dist/generated/locales/en.d.ts +3 -0
- package/dist/generated/locales/en.d.ts.map +1 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -0
- package/dist/locales/be.js +4 -1
- package/dist/locales/de.js +3 -0
- package/dist/locales/en.js +4 -1
- package/dist/pd-calendar/PdCalendar.d.ts +101 -18
- package/dist/pd-calendar/PdCalendar.d.ts.map +1 -1
- package/dist/pd-calendar/PdCalendar.js +380 -264
- package/dist/pd-calendar/pd-calendar-cell/PdCalendarCell.d.ts +40 -33
- package/dist/pd-calendar/pd-calendar-cell/PdCalendarCell.d.ts.map +1 -1
- package/dist/pd-calendar/pd-calendar-cell/PdCalendarCell.js +173 -113
- package/dist/pd-calendar/pd-calendar-day-events-panel/PdCalendarDayEventsPanel.d.ts +27 -0
- package/dist/pd-calendar/pd-calendar-day-events-panel/PdCalendarDayEventsPanel.d.ts.map +1 -0
- package/dist/pd-calendar/pd-calendar-day-events-panel/PdCalendarDayEventsPanel.js +160 -0
- package/dist/pd-calendar/pd-calendar-day-events-panel/pd-calendar-day-events-panel.d.ts +3 -0
- package/dist/pd-calendar/pd-calendar-day-events-panel/pd-calendar-day-events-panel.d.ts.map +1 -0
- package/dist/pd-calendar/pd-calendar-day-events-panel/pd-calendar-day-events-panel.js +8 -0
- package/dist/pd-calendar/pd-calendar-event-cell/PdCalendarEventCell.d.ts +55 -0
- package/dist/pd-calendar/pd-calendar-event-cell/PdCalendarEventCell.d.ts.map +1 -0
- package/dist/pd-calendar/pd-calendar-event-cell/PdCalendarEventCell.js +341 -0
- package/dist/pd-calendar/pd-calendar-event-cell/pd-calendar-event-cell.d.ts +3 -0
- package/dist/pd-calendar/pd-calendar-event-cell/pd-calendar-event-cell.d.ts.map +1 -0
- package/dist/pd-calendar/pd-calendar-event-cell/pd-calendar-event-cell.js +8 -0
- package/dist/pd-calendar/pd-calendar-event-info-panel/PdCalendarEventInfoPanel.d.ts +29 -0
- package/dist/pd-calendar/pd-calendar-event-info-panel/PdCalendarEventInfoPanel.d.ts.map +1 -0
- package/dist/pd-calendar/pd-calendar-event-info-panel/PdCalendarEventInfoPanel.js +211 -0
- package/dist/pd-calendar/pd-calendar-event-info-panel/pd-calendar-event-info-panel.d.ts +3 -0
- package/dist/pd-calendar/pd-calendar-event-info-panel/pd-calendar-event-info-panel.d.ts.map +1 -0
- package/dist/pd-calendar/pd-calendar-event-info-panel/pd-calendar-event-info-panel.js +8 -0
- package/dist/pd-calendar/pd-calendar-list-cell/PdCalendarListCell.d.ts +28 -0
- package/dist/pd-calendar/pd-calendar-list-cell/PdCalendarListCell.d.ts.map +1 -0
- package/dist/pd-calendar/pd-calendar-list-cell/PdCalendarListCell.js +252 -0
- package/dist/pd-calendar/pd-calendar-list-cell/pd-calendar-list-cell.d.ts +3 -0
- package/dist/pd-calendar/pd-calendar-list-cell/pd-calendar-list-cell.d.ts.map +1 -0
- package/dist/pd-calendar/pd-calendar-list-cell/pd-calendar-list-cell.js +8 -0
- package/dist/pd-calendar/pd-calendar-list-view/PdCalendarListView.d.ts +26 -0
- package/dist/pd-calendar/pd-calendar-list-view/PdCalendarListView.d.ts.map +1 -0
- package/dist/pd-calendar/pd-calendar-list-view/PdCalendarListView.js +165 -0
- package/dist/pd-calendar/pd-calendar-list-view/pd-calendar-list-view.d.ts +3 -0
- package/dist/pd-calendar/pd-calendar-list-view/pd-calendar-list-view.d.ts.map +1 -0
- package/dist/pd-calendar/pd-calendar-list-view/pd-calendar-list-view.js +8 -0
- package/dist/pd-calendar/pd-calendar-month-view/PdCalendarMonthView.d.ts +55 -0
- package/dist/pd-calendar/pd-calendar-month-view/PdCalendarMonthView.d.ts.map +1 -0
- package/dist/pd-calendar/pd-calendar-month-view/PdCalendarMonthView.js +461 -0
- package/dist/pd-calendar/pd-calendar-month-view/pd-calendar-month-view.d.ts +3 -0
- package/dist/pd-calendar/pd-calendar-month-view/pd-calendar-month-view.d.ts.map +1 -0
- package/dist/pd-calendar/pd-calendar-month-view/pd-calendar-month-view.js +8 -0
- package/dist/pd-calendar/pd-calendar-time-grid-view/PdCalendarTimeGridView.d.ts +32 -0
- package/dist/pd-calendar/pd-calendar-time-grid-view/PdCalendarTimeGridView.d.ts.map +1 -0
- package/dist/pd-calendar/pd-calendar-time-grid-view/PdCalendarTimeGridView.js +468 -0
- package/dist/pd-calendar/pd-calendar-time-grid-view/pd-calendar-time-grid-view.d.ts +3 -0
- package/dist/pd-calendar/pd-calendar-time-grid-view/pd-calendar-time-grid-view.d.ts.map +1 -0
- package/dist/pd-calendar/pd-calendar-time-grid-view/pd-calendar-time-grid-view.js +8 -0
- package/dist/pd-calendar/pd-calendar-week-cell/PdCalendarWeekCell.d.ts +31 -0
- package/dist/pd-calendar/pd-calendar-week-cell/PdCalendarWeekCell.d.ts.map +1 -0
- package/dist/pd-calendar/pd-calendar-week-cell/PdCalendarWeekCell.js +134 -0
- package/dist/pd-calendar/pd-calendar-week-cell/pd-calendar-week-cell.d.ts +3 -0
- package/dist/pd-calendar/pd-calendar-week-cell/pd-calendar-week-cell.d.ts.map +1 -0
- package/dist/pd-calendar/pd-calendar-week-cell/pd-calendar-week-cell.js +8 -0
- package/dist/pd-calendar/pd-calendar.stories.d.ts +79 -19
- package/dist/pd-calendar/pd-calendar.stories.d.ts.map +1 -1
- package/dist/pd-calendar/pd-year-popup/PdYearPopup.d.ts +22 -11
- package/dist/pd-calendar/pd-year-popup/PdYearPopup.d.ts.map +1 -1
- package/dist/pd-calendar/pd-year-popup/PdYearPopup.js +152 -34
- package/dist/pd-datepicker/PdDatepicker.d.ts +76 -7
- package/dist/pd-datepicker/PdDatepicker.d.ts.map +1 -1
- package/dist/pd-datepicker/PdDatepicker.js +257 -50
- package/dist/pd-datepicker/pd-date-picker.stories.d.ts +78 -20
- package/dist/pd-datepicker/pd-date-picker.stories.d.ts.map +1 -1
- package/dist/pd-slot-picker/PdSlotPicker.d.ts +102 -0
- package/dist/pd-slot-picker/PdSlotPicker.d.ts.map +1 -0
- package/dist/pd-slot-picker/PdSlotPicker.js +339 -0
- package/dist/pd-slot-picker/pd-slot-cell/PdSlotCell.d.ts +35 -0
- package/dist/pd-slot-picker/pd-slot-cell/PdSlotCell.d.ts.map +1 -0
- package/dist/pd-slot-picker/pd-slot-cell/PdSlotCell.js +188 -0
- package/dist/pd-slot-picker/pd-slot-cell/pd-slot-cell.d.ts +3 -0
- package/dist/pd-slot-picker/pd-slot-cell/pd-slot-cell.d.ts.map +1 -0
- package/dist/pd-slot-picker/pd-slot-cell/pd-slot-cell.js +8 -0
- package/dist/pd-slot-picker/pd-slot-picker.d.ts +3 -0
- package/dist/pd-slot-picker/pd-slot-picker.d.ts.map +1 -0
- package/dist/pd-slot-picker/pd-slot-picker.stories.d.ts +67 -0
- package/dist/pd-slot-picker/pd-slot-picker.stories.d.ts.map +1 -0
- package/dist/pd-slot-picker.d.ts +2 -0
- package/dist/pd-slot-picker.js +8 -0
- package/dist/shared/PdBaseCell.d.ts +68 -0
- package/dist/shared/PdBaseCell.d.ts.map +1 -0
- package/dist/shared/PdBaseCell.js +120 -0
- package/dist/shared/PdBaseView.d.ts +22 -0
- package/dist/shared/PdBaseView.d.ts.map +1 -0
- package/dist/shared/PdBaseView.js +46 -0
- package/dist/shared/PdCalendarPanelBase.d.ts +34 -0
- package/dist/shared/PdCalendarPanelBase.d.ts.map +1 -0
- package/dist/shared/PdCalendarPanelBase.js +169 -0
- package/dist/shared/calendar-button-bar/calendar-button-bar.d.ts +41 -0
- package/dist/shared/calendar-button-bar/calendar-button-bar.d.ts.map +1 -0
- package/dist/shared/calendar-button-bar/calendar-button-bar.js +435 -0
- package/dist/shared/calendar-locales.d.ts +9 -0
- package/dist/shared/calendar-locales.d.ts.map +1 -0
- package/dist/shared/calendar-locales.js +30 -0
- package/dist/shared/calendar-utils.d.ts +34 -0
- package/dist/shared/calendar-utils.d.ts.map +1 -0
- package/dist/shared/calendar-utils.js +99 -0
- package/dist/shared/calendar-utils.test.d.ts +2 -0
- package/dist/shared/calendar-utils.test.d.ts.map +1 -0
- package/dist/types.d.ts +102 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +10 -5
- package/dist/pd-calendar/pd-calendar-cell/pd-calendar-cell.stories.d.ts +0 -15
- package/dist/pd-calendar/pd-calendar-cell/pd-calendar-cell.stories.d.ts.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { css, html } from 'lit';
|
|
1
|
+
import { css, nothing, html } from 'lit';
|
|
2
2
|
import { localized, msg } from '@lit/localize';
|
|
3
3
|
import { property, state } from 'lit/decorators.js';
|
|
4
4
|
import { parse, format } from 'date-fns';
|
|
@@ -22,8 +22,7 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
22
22
|
const UNDEF = "UNDEF";
|
|
23
23
|
const INPUT_TYPE_DATE = 7;
|
|
24
24
|
const DEFAULT_FORMAT = "yyyy-MM-dd";
|
|
25
|
-
const
|
|
26
|
-
{ name: "Uhrzeit auswählen", value: UNDEF },
|
|
25
|
+
const TIME_VALUES = [
|
|
27
26
|
{ name: "07:00", value: "07:00" },
|
|
28
27
|
{ name: "07:30", value: "07:30" },
|
|
29
28
|
{ name: "08:00", value: "08:00" },
|
|
@@ -63,7 +62,7 @@ function getDataForDaysBetween(start, end) {
|
|
|
63
62
|
let to = new Date(end);
|
|
64
63
|
if (from > to) [from, to] = [to, from];
|
|
65
64
|
while (from <= to) {
|
|
66
|
-
result[format(from, DEFAULT_FORMAT)] = [{
|
|
65
|
+
result[format(from, DEFAULT_FORMAT)] = [{ category: "range" }];
|
|
67
66
|
from.setDate(from.getDate() + 1);
|
|
68
67
|
}
|
|
69
68
|
return result;
|
|
@@ -75,12 +74,38 @@ let PdDatepicker = class extends PdBaseInputElement {
|
|
|
75
74
|
this.hideToday = false;
|
|
76
75
|
this.withYearPopup = [];
|
|
77
76
|
this.withTime = false;
|
|
77
|
+
this.disabledDays = [];
|
|
78
|
+
this.modal = false;
|
|
79
|
+
this.modalBreakpoint = 480;
|
|
78
80
|
this._showCalendar = false;
|
|
79
81
|
this._timeSelection = UNDEF;
|
|
82
|
+
this._useModal = false;
|
|
83
|
+
this._displayedMonth = /* @__PURE__ */ new Date();
|
|
84
|
+
/** @ignore */
|
|
80
85
|
this._calendarPosition = "bottom";
|
|
81
86
|
this._inputType = INPUT_TYPE_DATE;
|
|
82
87
|
this._validators = [this._requiredDateTimeValidator.bind(this)];
|
|
83
88
|
}
|
|
89
|
+
/** Time selection options with i18n placeholder. */
|
|
90
|
+
get _timeOptions() {
|
|
91
|
+
return [
|
|
92
|
+
{
|
|
93
|
+
name: msg("Uhrzeit auswählen", { id: "pd.datepicker.selectTime" }),
|
|
94
|
+
value: UNDEF
|
|
95
|
+
},
|
|
96
|
+
...TIME_VALUES
|
|
97
|
+
];
|
|
98
|
+
}
|
|
99
|
+
disconnectedCallback() {
|
|
100
|
+
super.disconnectedCallback();
|
|
101
|
+
if (this._boundHandleClickOutside) {
|
|
102
|
+
document.removeEventListener("click", this._boundHandleClickOutside);
|
|
103
|
+
this._boundHandleClickOutside = void 0;
|
|
104
|
+
}
|
|
105
|
+
if (this._useModal && this._showCalendar) {
|
|
106
|
+
document.body.style.overflow = "";
|
|
107
|
+
}
|
|
108
|
+
}
|
|
84
109
|
_requiredDateTimeValidator() {
|
|
85
110
|
return this.required && !this._startDateValue || this.dateRange && this._startDateValue && !this._endDateValue || this.withTime && this._startDateValue && this._timeSelection === UNDEF ? msg("Eingabe unvollständig", {
|
|
86
111
|
id: "pd.form.field.selectDateTimeRequired"
|
|
@@ -89,11 +114,12 @@ let PdDatepicker = class extends PdBaseInputElement {
|
|
|
89
114
|
update(changedProps) {
|
|
90
115
|
if (changedProps.has("initialDate") && this.initialDate) {
|
|
91
116
|
this._prepareFieldsFromInitDate();
|
|
92
|
-
this._updateInputField(
|
|
117
|
+
this._updateInputField(this.handleChangeForInitVal, void 0);
|
|
93
118
|
}
|
|
94
119
|
super.update(changedProps);
|
|
95
120
|
}
|
|
96
121
|
render() {
|
|
122
|
+
const popupId = `${this.id || "datepicker"}-popup`;
|
|
97
123
|
return html`
|
|
98
124
|
<pd-input
|
|
99
125
|
id="datePickerId"
|
|
@@ -105,38 +131,53 @@ let PdDatepicker = class extends PdBaseInputElement {
|
|
|
105
131
|
?required="${this.required}"
|
|
106
132
|
?disabled="${this.disabled}"
|
|
107
133
|
icon-right
|
|
134
|
+
aria-haspopup="dialog"
|
|
135
|
+
aria-expanded="${this._showCalendar}"
|
|
136
|
+
aria-controls="${popupId}"
|
|
108
137
|
@click="${this._inputClick}"
|
|
138
|
+
@keydown="${this._onInputKeyDown}"
|
|
109
139
|
@pd-form-element-change="${this._innerFormChange}"
|
|
110
140
|
@pd-form-element-blur="${this._innerBlur}"
|
|
111
141
|
@pd-form-element-focus="${this._innerFocus}"
|
|
112
142
|
@pd-form-element-register="${this._innerRegister}"
|
|
113
143
|
@enter-pressed="${this._innerEnter}"
|
|
114
|
-
>
|
|
115
|
-
<div slot="icon-right">
|
|
116
|
-
<slot name="icon-right"></slot>
|
|
117
|
-
</div>
|
|
118
|
-
></pd-input
|
|
119
|
-
>
|
|
144
|
+
></pd-input>
|
|
120
145
|
${this._renderErrorMsg()}
|
|
121
|
-
<div
|
|
146
|
+
<div
|
|
147
|
+
class="modal-backdrop ${this._useModal ? "active" : ""}"
|
|
148
|
+
@click="${this._closeCalendar}"
|
|
149
|
+
></div>
|
|
150
|
+
<div
|
|
151
|
+
id="${popupId}"
|
|
152
|
+
class="calendar-small ${this._useModal ? "modal" : this._calendarPosition}"
|
|
153
|
+
role="dialog"
|
|
154
|
+
aria-modal="true"
|
|
155
|
+
aria-label="${msg("Datum auswählen", {
|
|
156
|
+
id: "pd.datepicker.selectDate"
|
|
157
|
+
})}"
|
|
158
|
+
@keydown="${this._onPopupKeyDown}"
|
|
159
|
+
>
|
|
122
160
|
<pd-calendar
|
|
123
161
|
.withYearPopup="${this.withYearPopup}"
|
|
124
162
|
.refDate="${this._startDateValue}"
|
|
125
|
-
.data="${this.
|
|
163
|
+
.data="${this._buildConstrainedData(this._displayedMonth)}"
|
|
126
164
|
numberClass="center"
|
|
127
165
|
selectableDates
|
|
128
166
|
showSelection
|
|
167
|
+
withWheelNavigation
|
|
168
|
+
withTouchNavigation
|
|
129
169
|
prevMonthConstraint="-1"
|
|
130
170
|
nextMonthConstraint="-1"
|
|
131
171
|
@select-date="${this._triggerCalendarDateSelected}"
|
|
132
172
|
@mouse-enter-date="${this._triggerHoverCalculateRange}"
|
|
173
|
+
@change-month="${this._onCalendarMonthChange}"
|
|
133
174
|
></pd-calendar>
|
|
134
175
|
|
|
135
176
|
${this.withTime ? html`
|
|
136
177
|
<pd-select
|
|
137
178
|
class="date-time-select"
|
|
138
179
|
id="dateTimeSelectId"
|
|
139
|
-
.values="${
|
|
180
|
+
.values="${this._timeOptions}"
|
|
140
181
|
label="${msg("Uhrzeit", { id: "pd.datepicker.time" })}"
|
|
141
182
|
initValue="${this._timeSelection}"
|
|
142
183
|
required
|
|
@@ -149,13 +190,13 @@ let PdDatepicker = class extends PdBaseInputElement {
|
|
|
149
190
|
@pd-form-element-register="${this._innerRegister}"
|
|
150
191
|
@enter-pressed="${this._innerEnter}"
|
|
151
192
|
></pd-select>
|
|
152
|
-
` :
|
|
193
|
+
` : nothing}
|
|
153
194
|
|
|
154
195
|
<div class="bottom-buttons">
|
|
155
|
-
${!this.hideToday ? html`<pd-button
|
|
196
|
+
${!this.hideToday && !this.dateRange ? html`<pd-button
|
|
156
197
|
text="${msg("Heute", { id: "pd.datepicker.today" })}"
|
|
157
198
|
@button-clicked="${this._triggerSetTodayButton}"
|
|
158
|
-
></pd-button>` :
|
|
199
|
+
></pd-button>` : nothing}
|
|
159
200
|
<pd-button
|
|
160
201
|
text="${msg("Reset", { id: "pd.datepicker.reset" })}"
|
|
161
202
|
@button-clicked="${this._triggerResetButton}"
|
|
@@ -204,8 +245,10 @@ let PdDatepicker = class extends PdBaseInputElement {
|
|
|
204
245
|
return this._formatDateValue();
|
|
205
246
|
}
|
|
206
247
|
/**
|
|
207
|
-
*
|
|
248
|
+
* Returns the parsed date values.
|
|
249
|
+
* @returns Object with start and optional end date: `{ start?: Date; end?: Date }`
|
|
208
250
|
*/
|
|
251
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
209
252
|
_getParsedValue() {
|
|
210
253
|
return this.dateValues;
|
|
211
254
|
}
|
|
@@ -246,21 +289,104 @@ let PdDatepicker = class extends PdBaseInputElement {
|
|
|
246
289
|
);
|
|
247
290
|
}
|
|
248
291
|
/**
|
|
249
|
-
*
|
|
292
|
+
* Toggle view calendar on click into pd-input field.
|
|
250
293
|
*/
|
|
251
294
|
_inputClick() {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
295
|
+
if (this._showCalendar) {
|
|
296
|
+
this._closeCalendar();
|
|
297
|
+
} else {
|
|
298
|
+
this._openCalendar();
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Handle keyboard events on the input field.
|
|
303
|
+
* Enter toggles calendar, Space/ArrowDown opens, Escape closes.
|
|
304
|
+
*/
|
|
305
|
+
_onInputKeyDown(e) {
|
|
306
|
+
switch (e.key) {
|
|
307
|
+
case " ":
|
|
308
|
+
case "Enter":
|
|
309
|
+
e.preventDefault();
|
|
310
|
+
if (this._showCalendar) {
|
|
311
|
+
this._closeCalendar();
|
|
312
|
+
} else {
|
|
313
|
+
this._openCalendar();
|
|
314
|
+
}
|
|
315
|
+
break;
|
|
316
|
+
case "ArrowDown":
|
|
317
|
+
e.preventDefault();
|
|
318
|
+
if (!this._showCalendar) this._openCalendar();
|
|
319
|
+
break;
|
|
320
|
+
case "Escape":
|
|
321
|
+
if (this._showCalendar) {
|
|
322
|
+
e.preventDefault();
|
|
323
|
+
this._closeCalendar();
|
|
324
|
+
}
|
|
325
|
+
break;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Handle keyboard events within the popup.
|
|
330
|
+
*/
|
|
331
|
+
_onPopupKeyDown(e) {
|
|
332
|
+
if (e.key === "Escape") {
|
|
333
|
+
e.preventDefault();
|
|
334
|
+
e.stopPropagation();
|
|
335
|
+
this._closeCalendar();
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Open the calendar popup.
|
|
340
|
+
*/
|
|
341
|
+
_openCalendar() {
|
|
342
|
+
this._displayedMonth = this._startDateValue || /* @__PURE__ */ new Date();
|
|
343
|
+
this._useModal = this.modal || window.innerWidth < this.modalBreakpoint;
|
|
344
|
+
if (!this._useModal) {
|
|
345
|
+
const input = this.shadowRoot?.getElementById("datePickerId");
|
|
346
|
+
if (input) {
|
|
347
|
+
const rect = input.getBoundingClientRect();
|
|
348
|
+
const spaceBelow = window.innerHeight - rect.bottom;
|
|
349
|
+
const spaceAbove = rect.top;
|
|
350
|
+
this._calendarPosition = spaceBelow < 380 && spaceAbove > spaceBelow ? "top" : "bottom";
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
if (this._useModal) {
|
|
354
|
+
document.body.style.overflow = "hidden";
|
|
355
|
+
}
|
|
356
|
+
this._showCalendar = true;
|
|
357
|
+
if (!this._useModal) {
|
|
259
358
|
setTimeout(() => {
|
|
260
|
-
this.
|
|
359
|
+
this._boundHandleClickOutside = this._handleClickOutside.bind(this);
|
|
360
|
+
document.addEventListener("click", this._boundHandleClickOutside);
|
|
261
361
|
}, 0);
|
|
262
362
|
}
|
|
263
363
|
}
|
|
364
|
+
/**
|
|
365
|
+
* Close the calendar popup and return focus to input.
|
|
366
|
+
*/
|
|
367
|
+
_closeCalendar() {
|
|
368
|
+
this._showCalendar = false;
|
|
369
|
+
if (this._useModal) {
|
|
370
|
+
document.body.style.overflow = "";
|
|
371
|
+
}
|
|
372
|
+
if (this._boundHandleClickOutside) {
|
|
373
|
+
document.removeEventListener("click", this._boundHandleClickOutside);
|
|
374
|
+
this._boundHandleClickOutside = void 0;
|
|
375
|
+
}
|
|
376
|
+
const input = this.shadowRoot?.getElementById(
|
|
377
|
+
"datePickerId"
|
|
378
|
+
);
|
|
379
|
+
input?.focus();
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Handle clicks outside the popup.
|
|
383
|
+
*/
|
|
384
|
+
_handleClickOutside(e) {
|
|
385
|
+
const path = e.composedPath();
|
|
386
|
+
if (!path.includes(this)) {
|
|
387
|
+
this._closeCalendar();
|
|
388
|
+
}
|
|
389
|
+
}
|
|
264
390
|
/**
|
|
265
391
|
* Triggered by date selection in small calendar.
|
|
266
392
|
* Set internal values depending on daterange configuration.
|
|
@@ -280,7 +406,7 @@ let PdDatepicker = class extends PdBaseInputElement {
|
|
|
280
406
|
} else {
|
|
281
407
|
this._endDateValue = date;
|
|
282
408
|
}
|
|
283
|
-
this.
|
|
409
|
+
this._closeCalendar();
|
|
284
410
|
} else {
|
|
285
411
|
this._startDateValue = date;
|
|
286
412
|
this._endDateValue = void 0;
|
|
@@ -293,7 +419,7 @@ let PdDatepicker = class extends PdBaseInputElement {
|
|
|
293
419
|
);
|
|
294
420
|
el?.focus();
|
|
295
421
|
} else {
|
|
296
|
-
this.
|
|
422
|
+
this._closeCalendar();
|
|
297
423
|
}
|
|
298
424
|
}
|
|
299
425
|
if (!this._showCalendar) {
|
|
@@ -310,8 +436,11 @@ let PdDatepicker = class extends PdBaseInputElement {
|
|
|
310
436
|
if (this.dateRange) {
|
|
311
437
|
this._endDateValue = void 0;
|
|
312
438
|
this._rangeSelection = void 0;
|
|
313
|
-
} else {
|
|
314
|
-
this.
|
|
439
|
+
} else if (!this.withTime) {
|
|
440
|
+
this._closeCalendar();
|
|
441
|
+
this._updateInputField(true, e);
|
|
442
|
+
e.stopPropagation();
|
|
443
|
+
return;
|
|
315
444
|
}
|
|
316
445
|
this._updateInputField(!this._showCalendar, e);
|
|
317
446
|
e.stopPropagation();
|
|
@@ -322,8 +451,7 @@ let PdDatepicker = class extends PdBaseInputElement {
|
|
|
322
451
|
*/
|
|
323
452
|
_triggerResetButton(e) {
|
|
324
453
|
this.reset();
|
|
325
|
-
this.
|
|
326
|
-
this.shadowRoot?.getElementById("datePickerId")?.reset();
|
|
454
|
+
this._closeCalendar();
|
|
327
455
|
e.stopPropagation();
|
|
328
456
|
}
|
|
329
457
|
/**
|
|
@@ -332,7 +460,17 @@ let PdDatepicker = class extends PdBaseInputElement {
|
|
|
332
460
|
*/
|
|
333
461
|
_triggerSetValueButton(e) {
|
|
334
462
|
this._updateInputField(true, e);
|
|
335
|
-
this.
|
|
463
|
+
this._closeCalendar();
|
|
464
|
+
e.stopPropagation();
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Handle month change from calendar navigation.
|
|
468
|
+
* Updates _displayedMonth to recalculate constraints for the new month.
|
|
469
|
+
*/
|
|
470
|
+
_onCalendarMonthChange(e) {
|
|
471
|
+
if (e.detail.newDate) {
|
|
472
|
+
this._displayedMonth = e.detail.newDate;
|
|
473
|
+
}
|
|
336
474
|
e.stopPropagation();
|
|
337
475
|
}
|
|
338
476
|
/**
|
|
@@ -368,6 +506,29 @@ let PdDatepicker = class extends PdBaseInputElement {
|
|
|
368
506
|
this.dateFormat
|
|
369
507
|
);
|
|
370
508
|
}
|
|
509
|
+
/**
|
|
510
|
+
* Builds calendar data with disabled days based on min/max constraints and disabledDays.
|
|
511
|
+
* Merges with existing range selection data.
|
|
512
|
+
*/
|
|
513
|
+
_buildConstrainedData(currentMonth) {
|
|
514
|
+
const result = { ...this._rangeSelection || {} };
|
|
515
|
+
const minDate = this.min ? parse(this.min, DEFAULT_FORMAT, /* @__PURE__ */ new Date()) : null;
|
|
516
|
+
const maxDate = this.max ? parse(this.max, DEFAULT_FORMAT, /* @__PURE__ */ new Date()) : null;
|
|
517
|
+
const year = currentMonth.getFullYear();
|
|
518
|
+
const month = currentMonth.getMonth();
|
|
519
|
+
const firstDay = new Date(year, month, 1);
|
|
520
|
+
const lastDay = new Date(year, month + 1, 0);
|
|
521
|
+
for (let day = new Date(firstDay); day <= lastDay; day.setDate(day.getDate() + 1)) {
|
|
522
|
+
const key = format(day, DEFAULT_FORMAT);
|
|
523
|
+
const isBeforeMin = minDate && day < minDate;
|
|
524
|
+
const isAfterMax = maxDate && day > maxDate;
|
|
525
|
+
const isInDisabledDays = this.disabledDays.includes(key);
|
|
526
|
+
if (isBeforeMin || isAfterMax || isInDisabledDays) {
|
|
527
|
+
result[key] = [{ ...result[key]?.[0], disabled: true }];
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
return result;
|
|
531
|
+
}
|
|
371
532
|
// ###### Start Inner Element Events
|
|
372
533
|
_innerEnter(e) {
|
|
373
534
|
e.stopPropagation();
|
|
@@ -393,6 +554,7 @@ PdDatepicker.styles = [
|
|
|
393
554
|
css`
|
|
394
555
|
:host {
|
|
395
556
|
position: relative;
|
|
557
|
+
display: inline-block;
|
|
396
558
|
}
|
|
397
559
|
|
|
398
560
|
:host([disabled]) {
|
|
@@ -406,26 +568,18 @@ PdDatepicker.styles = [
|
|
|
406
568
|
|
|
407
569
|
.calendar-small {
|
|
408
570
|
position: absolute;
|
|
409
|
-
background-color:
|
|
571
|
+
background-color: var(--pd-default-bg-col);
|
|
410
572
|
visibility: hidden;
|
|
411
|
-
z-index: 1000;
|
|
412
|
-
box-shadow: var(--pd-menu-shadow,
|
|
573
|
+
z-index: var(--pd-datepicker-z-index, 1000);
|
|
574
|
+
box-shadow: var(--pd-menu-shadow, var(--pd-shadow-lg));
|
|
413
575
|
transition: 0.5s ease-out;
|
|
414
576
|
transform: translateY(0);
|
|
415
577
|
opacity: 0;
|
|
416
|
-
padding: 0.5em
|
|
417
|
-
|
|
418
|
-
--pd-calendar-width: var(--pd-input-field-width, 250px);
|
|
419
|
-
--pd-calendar-cell-height: 30px;
|
|
420
|
-
--pd-calendar-week-title-bg-col: white;
|
|
421
|
-
--pd-calendar-week-title-font-col: #0a3a48;
|
|
578
|
+
padding: 0.5em;
|
|
579
|
+
max-width: 400px;
|
|
422
580
|
--pd-calendar-cell-selectable-shadow: 0;
|
|
423
|
-
--pd-calendar-cell-day-free-bg-col:
|
|
424
|
-
--pd-calendar-cell-day-info-free-col:
|
|
425
|
-
--pd-calendar-title-font-size: 20px;
|
|
426
|
-
--pd-calendar-title-icon-size: 20px;
|
|
427
|
-
--pd-calendar-weekday-title-font-size: 15px;
|
|
428
|
-
--pd-calendar-number-font-size: 15px;
|
|
581
|
+
--pd-calendar-cell-day-free-bg-col: var(--pd-default-bg-col);
|
|
582
|
+
--pd-calendar-cell-day-info-free-col: var(--pd-default-font-title-col);
|
|
429
583
|
}
|
|
430
584
|
|
|
431
585
|
.calendar-small.bottom {
|
|
@@ -436,9 +590,47 @@ PdDatepicker.styles = [
|
|
|
436
590
|
bottom: 100%; /* Über dem Input-Feld */
|
|
437
591
|
}
|
|
438
592
|
|
|
593
|
+
.date-time-select {
|
|
594
|
+
display: block;
|
|
595
|
+
--pd-input-field-height: 32px;
|
|
596
|
+
margin-top: var(--pd-spacing-sm);
|
|
597
|
+
}
|
|
598
|
+
|
|
439
599
|
.bottom-buttons {
|
|
440
600
|
display: flex;
|
|
441
|
-
--pd-button-
|
|
601
|
+
--pd-button-min-height: 32px;
|
|
602
|
+
--pd-button-height: 32px;
|
|
603
|
+
--pd-button-scale: 0.9;
|
|
604
|
+
gap: var(--pd-spacing-sm);
|
|
605
|
+
margin-top: var(--pd-spacing-sm);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
/* Modal backdrop overlay */
|
|
609
|
+
.modal-backdrop {
|
|
610
|
+
display: none;
|
|
611
|
+
position: fixed;
|
|
612
|
+
inset: 0;
|
|
613
|
+
background-color: var(--pd-modal-overlay-col, rgba(0, 0, 0, 0.5));
|
|
614
|
+
z-index: calc(var(--pd-datepicker-z-index, 1000) - 1);
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
:host([_showCalendar]) .modal-backdrop.active {
|
|
618
|
+
display: block;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
/* Modal mode: centered calendar, slightly above center for mobile usability */
|
|
622
|
+
.calendar-small.modal {
|
|
623
|
+
position: fixed;
|
|
624
|
+
top: 40%;
|
|
625
|
+
left: 50%;
|
|
626
|
+
transform: translate(-50%, -50%);
|
|
627
|
+
margin: 0;
|
|
628
|
+
padding: var(--pd-spacing-md);
|
|
629
|
+
border-radius: var(--pd-radius-lg);
|
|
630
|
+
max-height: 90vh;
|
|
631
|
+
min-height: 360px; /* Prevent jumping between months with different week counts */
|
|
632
|
+
overflow-y: auto;
|
|
633
|
+
width: calc(100vw - 2rem); /* 1rem Abstand links + rechts */
|
|
442
634
|
}
|
|
443
635
|
`
|
|
444
636
|
];
|
|
@@ -472,6 +664,15 @@ __decorateClass([
|
|
|
472
664
|
__decorateClass([
|
|
473
665
|
property({ type: String })
|
|
474
666
|
], PdDatepicker.prototype, "max", 2);
|
|
667
|
+
__decorateClass([
|
|
668
|
+
property({ type: Array })
|
|
669
|
+
], PdDatepicker.prototype, "disabledDays", 2);
|
|
670
|
+
__decorateClass([
|
|
671
|
+
property({ type: Boolean })
|
|
672
|
+
], PdDatepicker.prototype, "modal", 2);
|
|
673
|
+
__decorateClass([
|
|
674
|
+
property({ type: Number })
|
|
675
|
+
], PdDatepicker.prototype, "modalBreakpoint", 2);
|
|
475
676
|
__decorateClass([
|
|
476
677
|
property({ type: Boolean, reflect: true })
|
|
477
678
|
], PdDatepicker.prototype, "_showCalendar", 2);
|
|
@@ -487,6 +688,12 @@ __decorateClass([
|
|
|
487
688
|
__decorateClass([
|
|
488
689
|
state()
|
|
489
690
|
], PdDatepicker.prototype, "_timeSelection", 2);
|
|
691
|
+
__decorateClass([
|
|
692
|
+
state()
|
|
693
|
+
], PdDatepicker.prototype, "_useModal", 2);
|
|
694
|
+
__decorateClass([
|
|
695
|
+
state()
|
|
696
|
+
], PdDatepicker.prototype, "_displayedMonth", 2);
|
|
490
697
|
PdDatepicker = __decorateClass([
|
|
491
698
|
localized()
|
|
492
699
|
], PdDatepicker);
|
|
@@ -1,23 +1,81 @@
|
|
|
1
|
-
import { StoryObj } from '@storybook/web-components';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/web-components-vite';
|
|
2
|
+
/**
|
|
3
|
+
* Story arguments interface for pd-datepicker component.
|
|
4
|
+
* Maps to the component's public API.
|
|
5
|
+
*/
|
|
6
|
+
interface PdDatepickerArgs {
|
|
7
|
+
/** Field label */
|
|
8
|
+
label: string;
|
|
9
|
+
/** Placeholder text */
|
|
10
|
+
placeholder: string;
|
|
11
|
+
/** Whether the field is required */
|
|
12
|
+
required: boolean;
|
|
13
|
+
/** Whether the field is disabled */
|
|
14
|
+
disabled: boolean;
|
|
15
|
+
/** Whether to show time selection */
|
|
16
|
+
withTime: boolean;
|
|
17
|
+
/** Whether to enable date range selection */
|
|
18
|
+
dateRange: boolean;
|
|
19
|
+
/** Initial date value */
|
|
20
|
+
initialDate?: Date;
|
|
21
|
+
/** Date format string */
|
|
22
|
+
dateFormat: string;
|
|
23
|
+
/** Minimum allowed date (YYYY-MM-DD) */
|
|
24
|
+
min?: string;
|
|
25
|
+
/** Maximum allowed date (YYYY-MM-DD) */
|
|
26
|
+
max?: string;
|
|
27
|
+
/** Year selection popup values */
|
|
28
|
+
withYearPopup: string[];
|
|
29
|
+
/** Whether to hide today button */
|
|
30
|
+
hideToday: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* ## pd-datepicker
|
|
34
|
+
*
|
|
35
|
+
* A datepicker component for selecting dates with optional time and range support.
|
|
36
|
+
* Opens a calendar popup on click and integrates seamlessly with pd-form-container
|
|
37
|
+
* for validation.
|
|
38
|
+
*
|
|
39
|
+
* ### Features
|
|
40
|
+
* - **Date Selection**: Click to open calendar popup for date selection
|
|
41
|
+
* - **Time Selection**: Optional time picker with predefined time slots
|
|
42
|
+
* - **Date Range**: Optional range selection for start and end dates
|
|
43
|
+
* - **Year Popup**: Quick year navigation via dropdown
|
|
44
|
+
* - **Min/Max Constraints**: Limit selectable date range with `min` and `max` properties
|
|
45
|
+
* - **Disabled Days**: Disable specific dates via `disabledDays` array
|
|
46
|
+
* - **Modal Mode**: Centered modal display for mobile devices (auto or forced)
|
|
47
|
+
* - **Form Integration**: Works with pd-form-container for validation
|
|
48
|
+
* - **Popup Positioning**: Automatically opens above or below based on viewport space
|
|
49
|
+
*
|
|
50
|
+
* ### Accessibility
|
|
51
|
+
* - `aria-haspopup="dialog"` on the input field
|
|
52
|
+
* - `aria-expanded` reflects popup open/close state
|
|
53
|
+
* - `aria-controls` links input to popup
|
|
54
|
+
* - `aria-modal="true"` on the calendar popup
|
|
55
|
+
* - Keyboard: Enter/Space toggles popup, ArrowDown opens, Escape closes
|
|
56
|
+
* - Focus returns to input when popup closes
|
|
57
|
+
*/
|
|
58
|
+
declare const meta: Meta<PdDatepickerArgs>;
|
|
8
59
|
export default meta;
|
|
9
|
-
type Story = StoryObj
|
|
10
|
-
|
|
11
|
-
export declare const
|
|
12
|
-
|
|
13
|
-
export declare const
|
|
14
|
-
|
|
15
|
-
export declare const HugeYearSelection: Story;
|
|
16
|
-
export declare const Disabled: Story;
|
|
60
|
+
type Story = StoryObj<PdDatepickerArgs>;
|
|
61
|
+
/** Default datepicker. Interactive via Controls panel. */
|
|
62
|
+
export declare const Default: Story;
|
|
63
|
+
/** All datepicker configurations at a glance. */
|
|
64
|
+
export declare const AllVariants: Story;
|
|
65
|
+
/** Datepicker with time selection -- date + time picker combination. */
|
|
17
66
|
export declare const WithTime: Story;
|
|
18
|
-
|
|
19
|
-
export declare const
|
|
20
|
-
|
|
21
|
-
export declare const
|
|
22
|
-
|
|
67
|
+
/** Datepicker for selecting a start and end date. */
|
|
68
|
+
export declare const DateRange: Story;
|
|
69
|
+
/** Different date format locales side by side. */
|
|
70
|
+
export declare const Locales: Story;
|
|
71
|
+
/** Date constraints with min/max properties, disabled days, and linked datepickers. */
|
|
72
|
+
export declare const MinMaxDate: Story;
|
|
73
|
+
/** Modal mode displays the calendar centered on screen with a backdrop overlay. */
|
|
74
|
+
export declare const ModalMode: Story;
|
|
75
|
+
/** Datepicker within a pd-form-container with validation. */
|
|
76
|
+
export declare const InForm: Story;
|
|
77
|
+
/** Tests automatic popup positioning based on available viewport space. */
|
|
78
|
+
export declare const PopupPosition: Story;
|
|
79
|
+
/** CSS Custom Properties -- Branded and Redesigned datepicker variants. */
|
|
80
|
+
export declare const CustomStyling: Story;
|
|
23
81
|
//# sourceMappingURL=pd-date-picker.stories.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pd-date-picker.stories.d.ts","sourceRoot":"","sources":["../../src/pd-datepicker/pd-date-picker.stories.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pd-date-picker.stories.d.ts","sourceRoot":"","sources":["../../src/pd-datepicker/pd-date-picker.stories.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAKrE,OAAO,qDAAqD,CAAC;AAC7D,OAAO,+CAA+C,CAAC;AACvD,OAAO,6CAA6C,CAAC;AAErD,OAAO,oBAAoB,CAAC;AAM5B;;;GAGG;AACH,UAAU,gBAAgB;IACxB,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,oCAAoC;IACpC,QAAQ,EAAE,OAAO,CAAC;IAClB,oCAAoC;IACpC,QAAQ,EAAE,OAAO,CAAC;IAClB,qCAAqC;IACrC,QAAQ,EAAE,OAAO,CAAC;IAClB,6CAA6C;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,yBAAyB;IACzB,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,yBAAyB;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,mCAAmC;IACnC,SAAS,EAAE,OAAO,CAAC;CACpB;AAYD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,gBAAgB,CAoFhC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAC;AAMxC,0DAA0D;AAC1D,eAAO,MAAM,OAAO,EAAE,KAcrB,CAAC;AAMF,iDAAiD;AACjD,eAAO,MAAM,WAAW,EAAE,KAuEzB,CAAC;AAMF,wEAAwE;AACxE,eAAO,MAAM,QAAQ,EAAE,KA+BtB,CAAC;AAMF,qDAAqD;AACrD,eAAO,MAAM,SAAS,EAAE,KA4BvB,CAAC;AAMF,kDAAkD;AAClD,eAAO,MAAM,OAAO,EAAE,KA4CrB,CAAC;AAMF,uFAAuF;AACvF,eAAO,MAAM,UAAU,EAAE,KAqGxB,CAAC;AAMF,mFAAmF;AACnF,eAAO,MAAM,SAAS,EAAE,KA8DvB,CAAC;AAMF,6DAA6D;AAC7D,eAAO,MAAM,MAAM,EAAE,KA0EpB,CAAC;AAMF,2EAA2E;AAC3E,eAAO,MAAM,aAAa,EAAE,KAoC3B,CAAC;AAMF,2EAA2E;AAC3E,eAAO,MAAM,aAAa,EAAE,KA4G3B,CAAC"}
|