@triptease/tt-calendar 6.1.1 → 6.2.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/dist/cjs/src/DateSelectionContext.js +40 -0
- package/dist/cjs/src/DateSelectionContext.js.map +1 -0
- package/dist/cjs/src/Styles.js +267 -0
- package/dist/cjs/src/Styles.js.map +1 -0
- package/dist/cjs/src/TtCalendar.js +480 -0
- package/dist/cjs/src/TtCalendar.js.map +1 -0
- package/dist/cjs/src/helpers.js +9 -0
- package/dist/cjs/src/helpers.js.map +1 -0
- package/dist/cjs/src/index.js +6 -0
- package/dist/cjs/src/index.js.map +1 -0
- package/dist/cjs/src/tt-calendar.js +11 -0
- package/dist/cjs/src/tt-calendar.js.map +1 -0
- package/dist/esm/src/TtCalendar.d.ts +10 -1
- package/dist/esm/src/TtCalendar.js +114 -69
- package/dist/esm/src/TtCalendar.js.map +1 -1
- package/dist/esm/test/tt-calendar.test.js +62 -0
- package/dist/esm/test/tt-calendar.test.js.map +1 -1
- package/package.json +6 -2
- package/CHANGELOG.md +0 -117
- package/custom-elements.json +0 -668
- package/demo/index.html +0 -23
- package/test/tt-calendar.test.ts +0 -255
- package/tsconfig.cjs.json +0 -9
- package/tsconfig.json +0 -9
|
@@ -0,0 +1,480 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.Calendar = void 0;
|
|
10
|
+
const lit_1 = require("lit");
|
|
11
|
+
const decorators_js_1 = require("lit/decorators.js");
|
|
12
|
+
const class_map_js_1 = require("lit/directives/class-map.js");
|
|
13
|
+
const unsafe_svg_js_1 = require("lit/directives/unsafe-svg.js");
|
|
14
|
+
const luxon_1 = require("luxon");
|
|
15
|
+
const DateSelectionContext_js_1 = require("./DateSelectionContext.js");
|
|
16
|
+
const icons_1 = require("@triptease/icons");
|
|
17
|
+
const Styles_js_1 = require("./Styles.js");
|
|
18
|
+
const helpers_js_1 = require("./helpers.js");
|
|
19
|
+
class Calendar extends lit_1.LitElement {
|
|
20
|
+
constructor() {
|
|
21
|
+
super(...arguments);
|
|
22
|
+
this.range = false;
|
|
23
|
+
this.displayOnly = false;
|
|
24
|
+
this.highlightedRanges = [];
|
|
25
|
+
this._parsedHighlights = [];
|
|
26
|
+
this.focusedDate = this.today;
|
|
27
|
+
this.visible = false;
|
|
28
|
+
this.newWeek = () => new Array(7).fill(null);
|
|
29
|
+
this.handleButtonKeyDown = (event) => {
|
|
30
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
31
|
+
event.stopPropagation();
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
this.onDayHover = (event) => {
|
|
35
|
+
if (this.displayOnly)
|
|
36
|
+
return;
|
|
37
|
+
const day = event.target.dataset.date;
|
|
38
|
+
if (!day)
|
|
39
|
+
return;
|
|
40
|
+
this.focusedDate = luxon_1.DateTime.fromISO(day);
|
|
41
|
+
};
|
|
42
|
+
this.isStartDate = (date) => Boolean(this.isRange() && this.internalRangeValue?.startDate && this.internalRangeValue.startDate.equals(date));
|
|
43
|
+
this.isEndDate = (date) => Boolean(this.isRange() && this.internalRangeValue?.endDate && this.internalRangeValue.endDate.equals(date));
|
|
44
|
+
this.handleClearSelection = () => {
|
|
45
|
+
this.value = { startDate: undefined, endDate: undefined };
|
|
46
|
+
this.dispatchEvent(new DateSelectionContext_js_1.DateRangeSelectionEvent({ startDate: undefined, endDate: undefined }));
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
get internalRangeValue() {
|
|
50
|
+
if (this.range && this.value) {
|
|
51
|
+
const startDate = this.value?.startDate
|
|
52
|
+
? luxon_1.DateTime.fromISO(this.value.startDate)
|
|
53
|
+
: undefined;
|
|
54
|
+
const endDate = this.value?.endDate
|
|
55
|
+
? luxon_1.DateTime.fromISO(this.value.endDate)
|
|
56
|
+
: undefined;
|
|
57
|
+
return { startDate, endDate };
|
|
58
|
+
}
|
|
59
|
+
return { startDate: undefined, endDate: undefined };
|
|
60
|
+
}
|
|
61
|
+
getRange() {
|
|
62
|
+
if (this.range && this.internalRangeValue.startDate && this.internalRangeValue.endDate) {
|
|
63
|
+
return luxon_1.Interval.fromDateTimes(this.internalRangeValue.startDate, this.internalRangeValue.endDate.plus({ days: 1 }));
|
|
64
|
+
}
|
|
65
|
+
return luxon_1.Interval.invalid('Invalid range');
|
|
66
|
+
}
|
|
67
|
+
willUpdate(changedProperties) {
|
|
68
|
+
if (changedProperties.has('highlightedRanges')) {
|
|
69
|
+
this._parsedHighlights = this.highlightedRanges.map((range) => ({
|
|
70
|
+
start: luxon_1.DateTime.fromISO(range.startDate),
|
|
71
|
+
end: luxon_1.DateTime.fromISO(range.endDate),
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
updated(changedProperties) {
|
|
76
|
+
if (changedProperties.has('value') && this.value) {
|
|
77
|
+
super.updateComplete.then(() => {
|
|
78
|
+
if (!this.range) {
|
|
79
|
+
const parsedDate = luxon_1.DateTime.fromISO(this.value);
|
|
80
|
+
this.focusedDate = parsedDate.isValid ? parsedDate : this.today;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
this.focusedDate = this.internalRangeValue?.startDate || this.today;
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
super.updated(changedProperties);
|
|
88
|
+
}
|
|
89
|
+
toggleVisibility() {
|
|
90
|
+
if (this.visible) {
|
|
91
|
+
this.visible = false;
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
this.visible = true;
|
|
95
|
+
this.updateComplete.then(() => {
|
|
96
|
+
this.calendarDiv.focus();
|
|
97
|
+
this.calendarDiv.scrollIntoView({
|
|
98
|
+
behavior: 'smooth',
|
|
99
|
+
block: 'nearest',
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
if (!this.range) {
|
|
103
|
+
const parsedDate = luxon_1.DateTime.fromISO(this.value ?? this.today);
|
|
104
|
+
this.focusedDate = parsedDate.isValid ? parsedDate : this.today;
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
this.focusedDate = this.value?.startDate
|
|
108
|
+
? luxon_1.DateTime.fromISO(this.value.startDate)
|
|
109
|
+
: this.today;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
handleKeyDown(event) {
|
|
114
|
+
if (this.displayOnly)
|
|
115
|
+
return;
|
|
116
|
+
const currentDate = this.focusedDate;
|
|
117
|
+
switch (event.key) {
|
|
118
|
+
case 'ArrowLeft':
|
|
119
|
+
event.preventDefault();
|
|
120
|
+
this.focusDay(currentDate.minus({ day: 1 }));
|
|
121
|
+
break;
|
|
122
|
+
case 'ArrowRight':
|
|
123
|
+
event.preventDefault();
|
|
124
|
+
this.focusDay(currentDate.plus({ day: 1 }));
|
|
125
|
+
break;
|
|
126
|
+
case 'ArrowUp':
|
|
127
|
+
event.preventDefault();
|
|
128
|
+
this.focusDay(currentDate.minus({ week: 1 }));
|
|
129
|
+
break;
|
|
130
|
+
case 'ArrowDown':
|
|
131
|
+
event.preventDefault();
|
|
132
|
+
this.focusDay(currentDate.plus({ week: 1 }));
|
|
133
|
+
break;
|
|
134
|
+
case 'Home':
|
|
135
|
+
event.preventDefault();
|
|
136
|
+
// Move to first day of week
|
|
137
|
+
this.focusDay(currentDate.startOf('week'));
|
|
138
|
+
break;
|
|
139
|
+
case 'End':
|
|
140
|
+
event.preventDefault();
|
|
141
|
+
// Move to last day of week
|
|
142
|
+
this.focusDay(currentDate.endOf('week'));
|
|
143
|
+
break;
|
|
144
|
+
case 'PageUp':
|
|
145
|
+
event.preventDefault();
|
|
146
|
+
if (event.shiftKey) {
|
|
147
|
+
// Previous year
|
|
148
|
+
this.focusDay(currentDate.minus({ year: 1 }));
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
// Previous month
|
|
152
|
+
this.focusDay(currentDate.minus({ month: 1 }));
|
|
153
|
+
}
|
|
154
|
+
break;
|
|
155
|
+
case 'PageDown':
|
|
156
|
+
event.preventDefault();
|
|
157
|
+
if (event.shiftKey) {
|
|
158
|
+
// Next year
|
|
159
|
+
this.focusDay(currentDate.plus({ year: 1 }));
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
// Next month
|
|
163
|
+
this.focusDay(currentDate.plus({ month: 1 }));
|
|
164
|
+
}
|
|
165
|
+
break;
|
|
166
|
+
case 'Enter':
|
|
167
|
+
case ' ':
|
|
168
|
+
event.preventDefault();
|
|
169
|
+
this.handleDayClick(this.focusedDate);
|
|
170
|
+
return;
|
|
171
|
+
default:
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
event.preventDefault();
|
|
175
|
+
}
|
|
176
|
+
focusDay(date) {
|
|
177
|
+
this.focusedDate = date;
|
|
178
|
+
this.updateComplete.then(() => {
|
|
179
|
+
const dayElement = (this.shadowRoot?.querySelector(`.day[data-date="${date.toISODate()}"]`));
|
|
180
|
+
if (dayElement) {
|
|
181
|
+
dayElement.focus();
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
getDaysInMonth(date) {
|
|
186
|
+
const startOfMonth = date.startOf('month');
|
|
187
|
+
const endOfMonth = date.endOf('month');
|
|
188
|
+
const weeks = [];
|
|
189
|
+
let currentWeek = this.newWeek();
|
|
190
|
+
let currentDay = startOfMonth;
|
|
191
|
+
while (currentDay <= endOfMonth) {
|
|
192
|
+
// Get the day of week (0-6, Sunday=0, Saturday=6)
|
|
193
|
+
const dayOfWeek = currentDay.weekday === 7 ? 0 : currentDay.weekday;
|
|
194
|
+
currentWeek[dayOfWeek] = currentDay;
|
|
195
|
+
const isWeekComplete = dayOfWeek === 6; // Saturday (last day of week)
|
|
196
|
+
const isLastDayOfMonth = currentDay.hasSame(endOfMonth, 'day');
|
|
197
|
+
if (isWeekComplete || isLastDayOfMonth) {
|
|
198
|
+
weeks.push(currentWeek);
|
|
199
|
+
if (!isLastDayOfMonth) {
|
|
200
|
+
currentWeek = this.newWeek();
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
currentDay = currentDay.plus({ days: 1 });
|
|
204
|
+
}
|
|
205
|
+
return weeks;
|
|
206
|
+
}
|
|
207
|
+
previousYear() {
|
|
208
|
+
this.focusedDate = this.focusedDate.minus({ year: 1 });
|
|
209
|
+
}
|
|
210
|
+
previousMonth() {
|
|
211
|
+
this.focusedDate = this.focusedDate.minus({ month: 1 });
|
|
212
|
+
}
|
|
213
|
+
nextMonth() {
|
|
214
|
+
this.focusedDate = this.focusedDate.plus({ month: 1 });
|
|
215
|
+
}
|
|
216
|
+
nextYear() {
|
|
217
|
+
this.focusedDate = this.focusedDate.plus({ year: 1 });
|
|
218
|
+
}
|
|
219
|
+
get today() {
|
|
220
|
+
return luxon_1.DateTime.local();
|
|
221
|
+
}
|
|
222
|
+
handleDayClick(day) {
|
|
223
|
+
if (this.displayOnly)
|
|
224
|
+
return;
|
|
225
|
+
if (this.isRange()) {
|
|
226
|
+
if (!this.value?.startDate || this.value?.endDate) {
|
|
227
|
+
this.value = { startDate: day.toISODate() };
|
|
228
|
+
this.focusedDate = day;
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
if (!this.value.endDate) {
|
|
232
|
+
this.value = { ...this.value, endDate: day.toISODate() };
|
|
233
|
+
this.focusedDate = day;
|
|
234
|
+
this.dispatchEvent(new DateSelectionContext_js_1.DateRangeSelectionEvent(this.value));
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
if (day.isValid) {
|
|
239
|
+
this.dispatchEvent(new DateSelectionContext_js_1.DateSelectionEvent(day.toISODate()));
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
getWeekdayLabels() {
|
|
243
|
+
const monday = luxon_1.DateTime.fromISO('2024-06-02T00:00:00Z').startOf('week'); //Weeks start on Monday in Luxon https://moment.github.io/luxon/api-docs/index.html#datetimestartof
|
|
244
|
+
const sunday = monday.plus({ days: 6 });
|
|
245
|
+
return Array.from({ length: 7 }, (_, i) => {
|
|
246
|
+
const date = sunday.plus({ days: i });
|
|
247
|
+
return date.toLocaleString({ weekday: 'short' });
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
isSelected(date) {
|
|
251
|
+
if (date.equals(this.focusedDate))
|
|
252
|
+
return true;
|
|
253
|
+
if (this.isRange() && this.internalRangeValue.startDate) {
|
|
254
|
+
if (!this.internalRangeValue.endDate) {
|
|
255
|
+
const range = luxon_1.Interval.fromDateTimes(this.internalRangeValue.startDate, this.focusedDate.plus({ days: 1 }));
|
|
256
|
+
return range.contains(date);
|
|
257
|
+
}
|
|
258
|
+
const range = this.getRange();
|
|
259
|
+
return range.contains(date);
|
|
260
|
+
}
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
isInRange(date) {
|
|
264
|
+
if (!this.isRange() || !this.internalRangeValue?.startDate) {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
if (!this.internalRangeValue?.endDate) {
|
|
268
|
+
const range = luxon_1.Interval.fromDateTimes(this.internalRangeValue.startDate, this.focusedDate);
|
|
269
|
+
return range.contains(date) && !this.isStartDate(date) && !date.equals(this.focusedDate);
|
|
270
|
+
}
|
|
271
|
+
const range = this.getRange();
|
|
272
|
+
return range.contains(date) && !this.isStartDate(date) && !this.isEndDate(date);
|
|
273
|
+
}
|
|
274
|
+
isRange() {
|
|
275
|
+
return this.range;
|
|
276
|
+
}
|
|
277
|
+
get isSelectingRange() {
|
|
278
|
+
return Boolean(this.isRange() && this.value?.startDate && !this.value?.endDate);
|
|
279
|
+
}
|
|
280
|
+
isHighlighted(date) {
|
|
281
|
+
return this._parsedHighlights.some(({ start, end }) => date >= start && date <= end);
|
|
282
|
+
}
|
|
283
|
+
isHighlightedStart(date) {
|
|
284
|
+
return this._parsedHighlights.some(({ start, end }) => date.equals(start) && !start.equals(end));
|
|
285
|
+
}
|
|
286
|
+
isHighlightedEnd(date) {
|
|
287
|
+
return this._parsedHighlights.some(({ start, end }) => date.equals(end) && !start.equals(end));
|
|
288
|
+
}
|
|
289
|
+
isHighlightedInRange(date) {
|
|
290
|
+
return this._parsedHighlights.some(({ start, end }) => date > start && date < end);
|
|
291
|
+
}
|
|
292
|
+
handleToggle(e) {
|
|
293
|
+
const details = e.target;
|
|
294
|
+
if (details.open) {
|
|
295
|
+
details.scrollIntoView({
|
|
296
|
+
behavior: 'smooth',
|
|
297
|
+
block: 'nearest',
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
render() {
|
|
302
|
+
const displayDate = this.month ? luxon_1.DateTime.fromISO(this.month + '-01') : this.focusedDate;
|
|
303
|
+
const weeks = this.getDaysInMonth(displayDate);
|
|
304
|
+
const monthYear = displayDate.toLocaleString({
|
|
305
|
+
month: 'long',
|
|
306
|
+
year: 'numeric',
|
|
307
|
+
});
|
|
308
|
+
return (0, lit_1.html) `
|
|
309
|
+
<div class="calendar-panel" @keydown=${this.handleKeyDown} role="application" aria-label="${monthYear}">
|
|
310
|
+
${this.displayOnly
|
|
311
|
+
? lit_1.nothing
|
|
312
|
+
: (0, lit_1.html) `<div class="calendar-header">
|
|
313
|
+
<button
|
|
314
|
+
@click=${this.previousYear}
|
|
315
|
+
@keydown=${this.handleButtonKeyDown}
|
|
316
|
+
aria-label="Previous year"
|
|
317
|
+
class="compact"
|
|
318
|
+
>
|
|
319
|
+
${(0, unsafe_svg_js_1.unsafeSVG)(icons_1.doubleChevron)}
|
|
320
|
+
</button>
|
|
321
|
+
<button
|
|
322
|
+
@click=${this.previousMonth}
|
|
323
|
+
@keydown="${this.handleButtonKeyDown}"
|
|
324
|
+
aria-label="Previous month"
|
|
325
|
+
class="compact"
|
|
326
|
+
>
|
|
327
|
+
${(0, unsafe_svg_js_1.unsafeSVG)(icons_1.chevron)}
|
|
328
|
+
</button>
|
|
329
|
+
<h2>${monthYear}</h2>
|
|
330
|
+
<button
|
|
331
|
+
@click=${this.nextMonth}
|
|
332
|
+
@keydown="${this.handleButtonKeyDown}"
|
|
333
|
+
aria-label="Next month"
|
|
334
|
+
class="compact right"
|
|
335
|
+
>
|
|
336
|
+
${(0, unsafe_svg_js_1.unsafeSVG)(icons_1.chevron)}
|
|
337
|
+
</button>
|
|
338
|
+
<button
|
|
339
|
+
@click=${this.nextYear}
|
|
340
|
+
@keydown=${this.handleButtonKeyDown}
|
|
341
|
+
aria-label="Next year"
|
|
342
|
+
class="compact right"
|
|
343
|
+
>
|
|
344
|
+
${(0, unsafe_svg_js_1.unsafeSVG)(icons_1.doubleChevron)}
|
|
345
|
+
</button>
|
|
346
|
+
</div>`}
|
|
347
|
+
<div class="calendar-grid">
|
|
348
|
+
<table
|
|
349
|
+
role="grid"
|
|
350
|
+
aria-labelledby="month-year"
|
|
351
|
+
data-range="${this.range}"
|
|
352
|
+
class="${this.isSelectingRange ? 'selecting' : ''}"
|
|
353
|
+
>
|
|
354
|
+
<thead>
|
|
355
|
+
<tr>
|
|
356
|
+
${this.getWeekdayLabels().map((label) => (0, lit_1.html) ` <th>${label}</th>`)}
|
|
357
|
+
</tr>
|
|
358
|
+
</thead>
|
|
359
|
+
|
|
360
|
+
<tbody>
|
|
361
|
+
${weeks.map((week) => (0, lit_1.html) ` <tr>
|
|
362
|
+
${week.map((day) => {
|
|
363
|
+
if (!day) {
|
|
364
|
+
return (0, lit_1.html) ` <td></td>`;
|
|
365
|
+
}
|
|
366
|
+
const isDisabled = this.dayIsDisabled(day);
|
|
367
|
+
return (0, lit_1.html) ` <td
|
|
368
|
+
class="${(0, class_map_js_1.classMap)({
|
|
369
|
+
day: true,
|
|
370
|
+
'in-range': this.isInRange(day) || this.isHighlightedInRange(day),
|
|
371
|
+
'start-date': this.isStartDate(day) || this.isHighlightedStart(day),
|
|
372
|
+
'end-date': this.isEndDate(day) || this.isHighlightedEnd(day),
|
|
373
|
+
})}"
|
|
374
|
+
@click=${() => this.handleDayClick(day)}
|
|
375
|
+
role="gridcell"
|
|
376
|
+
data-date="${day.toISODate()}"
|
|
377
|
+
aria-label="${day.toLocaleString({ dateStyle: 'long' })}"
|
|
378
|
+
aria-selected="${this.isSelected(day) || this.isHighlighted(day)}"
|
|
379
|
+
aria-disabled="${isDisabled}"
|
|
380
|
+
tabindex="-1"
|
|
381
|
+
@mouseenter="${this.onDayHover}"
|
|
382
|
+
>
|
|
383
|
+
${day.day}
|
|
384
|
+
</td>`;
|
|
385
|
+
})}
|
|
386
|
+
</tr>`)}
|
|
387
|
+
</tbody>
|
|
388
|
+
</table>
|
|
389
|
+
</div>
|
|
390
|
+
|
|
391
|
+
${this.displayOnly
|
|
392
|
+
? lit_1.nothing
|
|
393
|
+
: (0, lit_1.html) `<div class="calendar-footer">
|
|
394
|
+
<div class="actions" @keydown="${this.handleButtonKeyDown}">
|
|
395
|
+
${this.isRange()
|
|
396
|
+
? (0, lit_1.html) `
|
|
397
|
+
<button @click=${() => this.handleClearSelection()} data-theme="secondary" id="clear-selection">
|
|
398
|
+
Clear selection
|
|
399
|
+
</button>
|
|
400
|
+
`
|
|
401
|
+
: (0, lit_1.html) `
|
|
402
|
+
<button @click=${() => this.handleDayClick(this.today)} data-theme="secondary">Today</button>
|
|
403
|
+
`}
|
|
404
|
+
</div>
|
|
405
|
+
<div>
|
|
406
|
+
<details @keydown=${this.handleButtonKeyDown} @toggle=${this.handleToggle}>
|
|
407
|
+
<summary>${(0, unsafe_svg_js_1.unsafeSVG)(icons_1.keyboard)} Keyboard commands ${(0, unsafe_svg_js_1.unsafeSVG)(icons_1.chevronDown)}</summary>
|
|
408
|
+
<p>Arrow keys: navigate the calendar</p>
|
|
409
|
+
<p>Enter or Space: select the date</p>
|
|
410
|
+
<p>Escape: close the calendar without selecting a date</p>
|
|
411
|
+
<p>Tab: navigate between the calendar and the presets</p>
|
|
412
|
+
<p>Home: move to first day of week</p>
|
|
413
|
+
<p>End: move to last day of week</p>
|
|
414
|
+
<p>Page Up: move to previous month</p>
|
|
415
|
+
<p>Page Down: move to next month</p>
|
|
416
|
+
<p>Shift + Page Up: move to next year</p>
|
|
417
|
+
<p>Shift + Page Down: move to previous year</p>
|
|
418
|
+
</details>
|
|
419
|
+
</div>
|
|
420
|
+
</div>`}
|
|
421
|
+
</div>
|
|
422
|
+
`;
|
|
423
|
+
}
|
|
424
|
+
dayIsDisabled(day) {
|
|
425
|
+
if (this.maxDate && day > this.maxDate)
|
|
426
|
+
return true;
|
|
427
|
+
if (this.minDate && day < this.minDate)
|
|
428
|
+
return true;
|
|
429
|
+
if (this.range && this.isSelectingRange && this.internalRangeValue?.startDate) {
|
|
430
|
+
if (day < this.internalRangeValue.startDate)
|
|
431
|
+
return true;
|
|
432
|
+
if (this.maxDays && day > this.internalRangeValue.startDate.plus({ days: this.maxDays }))
|
|
433
|
+
return true;
|
|
434
|
+
}
|
|
435
|
+
return false;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
exports.Calendar = Calendar;
|
|
439
|
+
Calendar.styles = Styles_js_1.styles;
|
|
440
|
+
Calendar.shadowRootOptions = {
|
|
441
|
+
...lit_1.LitElement.shadowRootOptions,
|
|
442
|
+
delegatesFocus: true,
|
|
443
|
+
};
|
|
444
|
+
__decorate([
|
|
445
|
+
(0, decorators_js_1.property)({ type: String })
|
|
446
|
+
], Calendar.prototype, "value", void 0);
|
|
447
|
+
__decorate([
|
|
448
|
+
(0, decorators_js_1.property)({ type: Boolean })
|
|
449
|
+
], Calendar.prototype, "range", void 0);
|
|
450
|
+
__decorate([
|
|
451
|
+
(0, decorators_js_1.property)({ attribute: 'max-date', converter: helpers_js_1.dateTimeConverter })
|
|
452
|
+
], Calendar.prototype, "maxDate", void 0);
|
|
453
|
+
__decorate([
|
|
454
|
+
(0, decorators_js_1.property)({ type: Number, attribute: 'max-days' })
|
|
455
|
+
], Calendar.prototype, "maxDays", void 0);
|
|
456
|
+
__decorate([
|
|
457
|
+
(0, decorators_js_1.property)({ attribute: 'min-date', converter: helpers_js_1.dateTimeConverter })
|
|
458
|
+
], Calendar.prototype, "minDate", void 0);
|
|
459
|
+
__decorate([
|
|
460
|
+
(0, decorators_js_1.property)({ type: Number, attribute: 'min-days' })
|
|
461
|
+
], Calendar.prototype, "minDays", void 0);
|
|
462
|
+
__decorate([
|
|
463
|
+
(0, decorators_js_1.property)({ type: Boolean, reflect: true, attribute: 'display-only' })
|
|
464
|
+
], Calendar.prototype, "displayOnly", void 0);
|
|
465
|
+
__decorate([
|
|
466
|
+
(0, decorators_js_1.property)({ type: String })
|
|
467
|
+
], Calendar.prototype, "month", void 0);
|
|
468
|
+
__decorate([
|
|
469
|
+
(0, decorators_js_1.property)({ attribute: false })
|
|
470
|
+
], Calendar.prototype, "highlightedRanges", void 0);
|
|
471
|
+
__decorate([
|
|
472
|
+
(0, decorators_js_1.query)('.calendar-panel')
|
|
473
|
+
], Calendar.prototype, "calendarDiv", void 0);
|
|
474
|
+
__decorate([
|
|
475
|
+
(0, decorators_js_1.state)()
|
|
476
|
+
], Calendar.prototype, "focusedDate", void 0);
|
|
477
|
+
__decorate([
|
|
478
|
+
(0, decorators_js_1.state)()
|
|
479
|
+
], Calendar.prototype, "visible", void 0);
|
|
480
|
+
//# sourceMappingURL=TtCalendar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TtCalendar.js","sourceRoot":"","sources":["../../../src/TtCalendar.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, LitElement, nothing, PropertyValues } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js';\nimport { DateTime, Interval } from 'luxon';\nimport { DateRange, DateRangeSelectionEvent, DateSelectionEvent } from './DateSelectionContext.js';\nimport { chevron, chevronDown, doubleChevron, keyboard } from '@triptease/icons';\nimport { styles } from './Styles.js';\nimport { dateTimeConverter } from './helpers.js';\n\ntype WeekdayList = [\n DateTime | null,\n DateTime | null,\n DateTime | null,\n DateTime | null,\n DateTime | null,\n DateTime | null,\n DateTime | null,\n];\n\ninterface CalendarWithRange {\n value?: DateRange;\n range: true;\n}\n\ninterface InternalDateRange {\n startDate?: DateTime;\n endDate?: DateTime;\n}\n\nexport class Calendar extends LitElement {\n static styles = styles;\n\n static shadowRootOptions = {\n ...LitElement.shadowRootOptions,\n delegatesFocus: true,\n };\n\n // Start public properties\n\n @property({ type: String })\n public value?: string | DateRange;\n\n @property({ type: Boolean })\n public range = false;\n\n @property({ attribute: 'max-date', converter: dateTimeConverter })\n public maxDate?: DateTime;\n\n @property({ type: Number, attribute: 'max-days' })\n public maxDays?: number;\n\n @property({ attribute: 'min-date', converter: dateTimeConverter })\n public minDate?: DateTime;\n\n @property({ type: Number, attribute: 'min-days' })\n public minDays?: number;\n\n @property({ type: Boolean, reflect: true, attribute: 'display-only' })\n public displayOnly: boolean = false;\n\n @property({ type: String })\n public month?: string;\n\n @property({ attribute: false })\n public highlightedRanges: Required<DateRange>[] = [];\n\n private _parsedHighlights: { start: DateTime; end: DateTime }[] = [];\n\n get internalRangeValue(): InternalDateRange {\n if (this.range && this.value) {\n const startDate = (this.value as DateRange)?.startDate\n ? DateTime.fromISO((this.value as DateRange).startDate!)\n : undefined;\n const endDate = (this.value as DateRange)?.endDate\n ? DateTime.fromISO((this.value as DateRange).endDate!)\n : undefined;\n return { startDate, endDate };\n }\n return { startDate: undefined, endDate: undefined };\n }\n\n getRange(): Interval {\n if (this.range && this.internalRangeValue.startDate && this.internalRangeValue.endDate) {\n return Interval.fromDateTimes(\n this.internalRangeValue.startDate,\n this.internalRangeValue.endDate.plus({ days: 1 })\n );\n }\n return Interval.invalid('Invalid range');\n }\n\n protected override willUpdate(changedProperties: PropertyValues) {\n if (changedProperties.has('highlightedRanges')) {\n this._parsedHighlights = this.highlightedRanges.map((range) => ({\n start: DateTime.fromISO(range.startDate),\n end: DateTime.fromISO(range.endDate),\n }));\n }\n }\n\n public updated(changedProperties: PropertyValues) {\n if (changedProperties.has('value') && this.value) {\n super.updateComplete.then(() => {\n if (!this.range) {\n const parsedDate = DateTime.fromISO(this.value as string);\n this.focusedDate = parsedDate.isValid ? parsedDate : this.today;\n } else {\n this.focusedDate = this.internalRangeValue?.startDate || this.today;\n }\n });\n }\n super.updated(changedProperties);\n }\n\n public toggleVisibility() {\n if (this.visible) {\n this.visible = false;\n } else {\n this.visible = true;\n this.updateComplete.then(() => {\n this.calendarDiv.focus();\n this.calendarDiv.scrollIntoView({\n behavior: 'smooth',\n block: 'nearest',\n });\n });\n if (!this.range) {\n const parsedDate = DateTime.fromISO((this.value as string) ?? this.today);\n this.focusedDate = parsedDate.isValid ? parsedDate : this.today;\n } else {\n this.focusedDate = (this.value as DateRange)?.startDate\n ? DateTime.fromISO((this.value as DateRange).startDate!)\n : this.today;\n }\n }\n }\n\n // end public properties\n\n @query('.calendar-panel')\n private calendarDiv!: HTMLElement;\n\n @state()\n private focusedDate: DateTime = this.today;\n\n @state()\n private visible: boolean = false;\n\n private handleKeyDown(event: KeyboardEvent) {\n if (this.displayOnly) return;\n const currentDate = this.focusedDate;\n switch (event.key) {\n case 'ArrowLeft':\n event.preventDefault();\n this.focusDay(currentDate.minus({ day: 1 }));\n break;\n case 'ArrowRight':\n event.preventDefault();\n this.focusDay(currentDate.plus({ day: 1 }));\n break;\n case 'ArrowUp':\n event.preventDefault();\n this.focusDay(currentDate.minus({ week: 1 }));\n break;\n case 'ArrowDown':\n event.preventDefault();\n this.focusDay(currentDate.plus({ week: 1 }));\n break;\n case 'Home':\n event.preventDefault();\n // Move to first day of week\n this.focusDay(currentDate.startOf('week'));\n break;\n case 'End':\n event.preventDefault();\n // Move to last day of week\n this.focusDay(currentDate.endOf('week'));\n break;\n case 'PageUp':\n event.preventDefault();\n if (event.shiftKey) {\n // Previous year\n this.focusDay(currentDate.minus({ year: 1 }));\n } else {\n // Previous month\n this.focusDay(currentDate.minus({ month: 1 }));\n }\n break;\n case 'PageDown':\n event.preventDefault();\n if (event.shiftKey) {\n // Next year\n this.focusDay(currentDate.plus({ year: 1 }));\n } else {\n // Next month\n this.focusDay(currentDate.plus({ month: 1 }));\n }\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n this.handleDayClick(this.focusedDate);\n return;\n\n default:\n return;\n }\n\n event.preventDefault();\n }\n\n public focusDay(date: DateTime) {\n this.focusedDate = date;\n this.updateComplete.then(() => {\n const dayElement = <HTMLElement | undefined>(\n this.shadowRoot?.querySelector(`.day[data-date=\"${date.toISODate()}\"]`)\n );\n if (dayElement) {\n dayElement.focus();\n }\n });\n }\n\n private newWeek = () => new Array(7).fill(null) as WeekdayList;\n\n private getDaysInMonth(date: DateTime): WeekdayList[] {\n const startOfMonth = date.startOf('month');\n const endOfMonth = date.endOf('month');\n\n const weeks: WeekdayList[] = [];\n let currentWeek: WeekdayList = this.newWeek();\n\n let currentDay = startOfMonth;\n\n while (currentDay <= endOfMonth) {\n // Get the day of week (0-6, Sunday=0, Saturday=6)\n const dayOfWeek = currentDay.weekday === 7 ? 0 : currentDay.weekday;\n\n currentWeek[dayOfWeek] = currentDay;\n\n const isWeekComplete = dayOfWeek === 6; // Saturday (last day of week)\n const isLastDayOfMonth = currentDay.hasSame(endOfMonth, 'day');\n\n if (isWeekComplete || isLastDayOfMonth) {\n weeks.push(currentWeek);\n\n if (!isLastDayOfMonth) {\n currentWeek = this.newWeek();\n }\n }\n\n currentDay = currentDay.plus({ days: 1 });\n }\n\n return weeks;\n }\n\n private previousYear() {\n this.focusedDate = this.focusedDate.minus({ year: 1 });\n }\n\n private previousMonth() {\n this.focusedDate = this.focusedDate.minus({ month: 1 });\n }\n\n private nextMonth() {\n this.focusedDate = this.focusedDate.plus({ month: 1 });\n }\n\n private nextYear() {\n this.focusedDate = this.focusedDate.plus({ year: 1 });\n }\n\n private get today(): DateTime {\n return DateTime.local();\n }\n\n private handleDayClick(day: DateTime) {\n if (this.displayOnly) return;\n if (this.isRange()) {\n if (!this.value?.startDate || this.value?.endDate) {\n this.value = { startDate: day.toISODate()! };\n this.focusedDate = day;\n return;\n }\n\n if (!this.value.endDate) {\n this.value = { ...(this.value as DateRange), endDate: day.toISODate()! };\n this.focusedDate = day;\n this.dispatchEvent(new DateRangeSelectionEvent(this.value));\n return;\n }\n }\n\n if (day.isValid) {\n this.dispatchEvent(new DateSelectionEvent(day.toISODate()!));\n }\n }\n\n private handleButtonKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.stopPropagation();\n }\n };\n\n private getWeekdayLabels(): string[] {\n const monday = DateTime.fromISO('2024-06-02T00:00:00Z').startOf('week'); //Weeks start on Monday in Luxon https://moment.github.io/luxon/api-docs/index.html#datetimestartof\n const sunday = monday.plus({ days: 6 });\n return Array.from({ length: 7 }, (_, i) => {\n const date = sunday.plus({ days: i });\n return date.toLocaleString({ weekday: 'short' });\n });\n }\n\n private isSelected(date: DateTime): boolean {\n if (date.equals(this.focusedDate)) return true;\n\n if (this.isRange() && this.internalRangeValue.startDate) {\n if (!this.internalRangeValue.endDate) {\n const range = Interval.fromDateTimes(this.internalRangeValue.startDate, this.focusedDate.plus({ days: 1 }));\n return range.contains(date);\n }\n\n const range = this.getRange();\n return range.contains(date);\n }\n\n return false;\n }\n\n private isInRange(date: DateTime): boolean {\n if (!this.isRange() || !this.internalRangeValue?.startDate) {\n return false;\n }\n\n if (!this.internalRangeValue?.endDate) {\n const range = Interval.fromDateTimes(this.internalRangeValue.startDate, this.focusedDate);\n return range.contains(date) && !this.isStartDate(date) && !date.equals(this.focusedDate);\n }\n\n const range = this.getRange();\n return range.contains(date) && !this.isStartDate(date) && !this.isEndDate(date);\n }\n\n private isRange(): this is CalendarWithRange {\n return this.range;\n }\n\n private get isSelectingRange(): boolean {\n return Boolean(this.isRange() && this.value?.startDate && !this.value?.endDate);\n }\n\n private onDayHover = (event: MouseEvent) => {\n if (this.displayOnly) return;\n const day = (event.target as HTMLElement).dataset.date;\n if (!day) return;\n\n this.focusedDate = DateTime.fromISO(day);\n };\n\n private isStartDate = (date: DateTime): boolean =>\n Boolean(this.isRange() && this.internalRangeValue?.startDate && this.internalRangeValue.startDate.equals(date));\n\n private isEndDate = (date: DateTime): boolean =>\n Boolean(this.isRange() && this.internalRangeValue?.endDate && this.internalRangeValue.endDate.equals(date));\n\n private handleClearSelection = () => {\n this.value = { startDate: undefined, endDate: undefined };\n this.dispatchEvent(new DateRangeSelectionEvent({ startDate: undefined, endDate: undefined }));\n };\n\n private isHighlighted(date: DateTime): boolean {\n return this._parsedHighlights.some(({ start, end }) => date >= start && date <= end);\n }\n\n private isHighlightedStart(date: DateTime): boolean {\n return this._parsedHighlights.some(({ start, end }) => date.equals(start) && !start.equals(end));\n }\n\n private isHighlightedEnd(date: DateTime): boolean {\n return this._parsedHighlights.some(({ start, end }) => date.equals(end) && !start.equals(end));\n }\n\n private isHighlightedInRange(date: DateTime): boolean {\n return this._parsedHighlights.some(({ start, end }) => date > start && date < end);\n }\n\n private handleToggle(e: Event) {\n const details = e.target as HTMLDetailsElement;\n if (details.open) {\n details.scrollIntoView({\n behavior: 'smooth',\n block: 'nearest',\n });\n }\n }\n\n render() {\n const displayDate = this.month ? DateTime.fromISO(this.month + '-01') : this.focusedDate;\n const weeks = this.getDaysInMonth(displayDate);\n const monthYear = displayDate.toLocaleString({\n month: 'long',\n year: 'numeric',\n });\n\n return html`\n <div class=\"calendar-panel\" @keydown=${this.handleKeyDown} role=\"application\" aria-label=\"${monthYear}\">\n ${this.displayOnly\n ? nothing\n : html`<div class=\"calendar-header\">\n <button\n @click=${this.previousYear}\n @keydown=${this.handleButtonKeyDown}\n aria-label=\"Previous year\"\n class=\"compact\"\n >\n ${unsafeSVG(doubleChevron)}\n </button>\n <button\n @click=${this.previousMonth}\n @keydown=\"${this.handleButtonKeyDown}\"\n aria-label=\"Previous month\"\n class=\"compact\"\n >\n ${unsafeSVG(chevron)}\n </button>\n <h2>${monthYear}</h2>\n <button\n @click=${this.nextMonth}\n @keydown=\"${this.handleButtonKeyDown}\"\n aria-label=\"Next month\"\n class=\"compact right\"\n >\n ${unsafeSVG(chevron)}\n </button>\n <button\n @click=${this.nextYear}\n @keydown=${this.handleButtonKeyDown}\n aria-label=\"Next year\"\n class=\"compact right\"\n >\n ${unsafeSVG(doubleChevron)}\n </button>\n </div>`}\n <div class=\"calendar-grid\">\n <table\n role=\"grid\"\n aria-labelledby=\"month-year\"\n data-range=\"${this.range}\"\n class=\"${this.isSelectingRange ? 'selecting' : ''}\"\n >\n <thead>\n <tr>\n ${this.getWeekdayLabels().map((label) => html` <th>${label}</th>`)}\n </tr>\n </thead>\n\n <tbody>\n ${weeks.map(\n (week) =>\n html` <tr>\n ${week.map((day) => {\n if (!day) {\n return html` <td></td>`;\n }\n\n const isDisabled = this.dayIsDisabled(day);\n\n return html` <td\n class=\"${classMap({\n day: true,\n 'in-range': this.isInRange(day) || this.isHighlightedInRange(day),\n 'start-date': this.isStartDate(day) || this.isHighlightedStart(day),\n 'end-date': this.isEndDate(day) || this.isHighlightedEnd(day),\n })}\"\n @click=${() => this.handleDayClick(day)}\n role=\"gridcell\"\n data-date=\"${day.toISODate()}\"\n aria-label=\"${day.toLocaleString({ dateStyle: 'long' })}\"\n aria-selected=\"${this.isSelected(day) || this.isHighlighted(day)}\"\n aria-disabled=\"${isDisabled}\"\n tabindex=\"-1\"\n @mouseenter=\"${this.onDayHover}\"\n >\n ${day.day}\n </td>`;\n })}\n </tr>`\n )}\n </tbody>\n </table>\n </div>\n\n ${this.displayOnly\n ? nothing\n : html`<div class=\"calendar-footer\">\n <div class=\"actions\" @keydown=\"${this.handleButtonKeyDown}\">\n ${this.isRange()\n ? html`\n <button @click=${() => this.handleClearSelection()} data-theme=\"secondary\" id=\"clear-selection\">\n Clear selection\n </button>\n `\n : html`\n <button @click=${() => this.handleDayClick(this.today)} data-theme=\"secondary\">Today</button>\n `}\n </div>\n <div>\n <details @keydown=${this.handleButtonKeyDown} @toggle=${this.handleToggle}>\n <summary>${unsafeSVG(keyboard)} Keyboard commands ${unsafeSVG(chevronDown)}</summary>\n <p>Arrow keys: navigate the calendar</p>\n <p>Enter or Space: select the date</p>\n <p>Escape: close the calendar without selecting a date</p>\n <p>Tab: navigate between the calendar and the presets</p>\n <p>Home: move to first day of week</p>\n <p>End: move to last day of week</p>\n <p>Page Up: move to previous month</p>\n <p>Page Down: move to next month</p>\n <p>Shift + Page Up: move to next year</p>\n <p>Shift + Page Down: move to previous year</p>\n </details>\n </div>\n </div>`}\n </div>\n `;\n }\n\n private dayIsDisabled(day: DateTime) {\n if (this.maxDate && day > this.maxDate) return true;\n\n if (this.minDate && day < this.minDate) return true;\n\n if (this.range && this.isSelectingRange && this.internalRangeValue?.startDate) {\n if (day < this.internalRangeValue.startDate) return true;\n\n if (this.maxDays && day > this.internalRangeValue.startDate.plus({ days: this.maxDays })) return true;\n }\n\n return false;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'tt-calendar': Calendar;\n }\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dateTimeConverter = exports.dateConverter = void 0;
|
|
4
|
+
const luxon_1 = require("luxon");
|
|
5
|
+
const dateConverter = (value) => value ? luxon_1.DateTime.fromISO(value).toJSDate() : undefined;
|
|
6
|
+
exports.dateConverter = dateConverter;
|
|
7
|
+
const dateTimeConverter = (value) => value ? luxon_1.DateTime.fromISO(value) : undefined;
|
|
8
|
+
exports.dateTimeConverter = dateTimeConverter;
|
|
9
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/helpers.ts"],"names":[],"mappings":";;;AAAA,iCAAiC;AAE1B,MAAM,aAAa,GAAG,CAAC,KAAoB,EAAoB,EAAE,CACtE,KAAK,CAAC,CAAC,CAAC,gBAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAD5C,QAAA,aAAa,iBAC+B;AAElD,MAAM,iBAAiB,GAAG,CAAC,KAAoB,EAAwB,EAAE,CAC9E,KAAK,CAAC,CAAC,CAAC,gBAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AADjC,QAAA,iBAAiB,qBACgB","sourcesContent":["import { DateTime } from 'luxon';\n\nexport const dateConverter = (value: string | null): Date | undefined =>\n value ? DateTime.fromISO(value).toJSDate() : undefined;\n\nexport const dateTimeConverter = (value: string | null): DateTime | undefined =>\n value ? DateTime.fromISO(value) : undefined;\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Calendar = void 0;
|
|
4
|
+
var tt_calendar_js_1 = require("./tt-calendar.js");
|
|
5
|
+
Object.defineProperty(exports, "Calendar", { enumerable: true, get: function () { return tt_calendar_js_1.Calendar; } });
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":";;;AAAA,mDAA4C;AAAnC,0GAAA,QAAQ,OAAA","sourcesContent":["export { Calendar } from './tt-calendar.js';\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Calendar = void 0;
|
|
4
|
+
const TtCalendar_js_1 = require("./TtCalendar.js");
|
|
5
|
+
Object.defineProperty(exports, "Calendar", { enumerable: true, get: function () { return TtCalendar_js_1.Calendar; } });
|
|
6
|
+
if (typeof window !== 'undefined') {
|
|
7
|
+
if (!window.customElements.get('tt-calendar')) {
|
|
8
|
+
window.customElements.define('tt-calendar', TtCalendar_js_1.Calendar);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=tt-calendar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tt-calendar.js","sourceRoot":"","sources":["../../../src/tt-calendar.ts"],"names":[],"mappings":";;;AAAA,mDAA2C;AAQlC,yFARA,wBAAQ,OAQA;AANjB,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;IAClC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;QAC9C,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,aAAa,EAAE,wBAAQ,CAAC,CAAC;IACxD,CAAC;AACH,CAAC","sourcesContent":["import { Calendar } from './TtCalendar.js';\n\nif (typeof window !== 'undefined') {\n if (!window.customElements.get('tt-calendar')) {\n window.customElements.define('tt-calendar', Calendar);\n }\n}\n\nexport { Calendar };\n"]}
|
|
@@ -21,15 +21,20 @@ export declare class Calendar extends LitElement {
|
|
|
21
21
|
maxDays?: number;
|
|
22
22
|
minDate?: DateTime;
|
|
23
23
|
minDays?: number;
|
|
24
|
+
displayOnly: boolean;
|
|
25
|
+
month?: string;
|
|
26
|
+
highlightedRanges: Required<DateRange>[];
|
|
27
|
+
private _parsedHighlights;
|
|
24
28
|
get internalRangeValue(): InternalDateRange;
|
|
25
29
|
getRange(): Interval;
|
|
30
|
+
protected willUpdate(changedProperties: PropertyValues): void;
|
|
26
31
|
updated(changedProperties: PropertyValues): void;
|
|
27
32
|
toggleVisibility(): void;
|
|
28
33
|
private calendarDiv;
|
|
29
34
|
private focusedDate;
|
|
30
35
|
private visible;
|
|
31
36
|
private handleKeyDown;
|
|
32
|
-
|
|
37
|
+
focusDay(date: DateTime): void;
|
|
33
38
|
private newWeek;
|
|
34
39
|
private getDaysInMonth;
|
|
35
40
|
private previousYear;
|
|
@@ -48,6 +53,10 @@ export declare class Calendar extends LitElement {
|
|
|
48
53
|
private isStartDate;
|
|
49
54
|
private isEndDate;
|
|
50
55
|
private handleClearSelection;
|
|
56
|
+
private isHighlighted;
|
|
57
|
+
private isHighlightedStart;
|
|
58
|
+
private isHighlightedEnd;
|
|
59
|
+
private isHighlightedInRange;
|
|
51
60
|
private handleToggle;
|
|
52
61
|
render(): import("lit-html").TemplateResult<1>;
|
|
53
62
|
private dayIsDisabled;
|