@triptease/tt-calendar 6.1.2 → 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/TtCalendar.js +113 -68
- package/dist/cjs/src/TtCalendar.js.map +1 -1
- 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 +1 -1
|
@@ -20,6 +20,9 @@ class Calendar extends lit_1.LitElement {
|
|
|
20
20
|
constructor() {
|
|
21
21
|
super(...arguments);
|
|
22
22
|
this.range = false;
|
|
23
|
+
this.displayOnly = false;
|
|
24
|
+
this.highlightedRanges = [];
|
|
25
|
+
this._parsedHighlights = [];
|
|
23
26
|
this.focusedDate = this.today;
|
|
24
27
|
this.visible = false;
|
|
25
28
|
this.newWeek = () => new Array(7).fill(null);
|
|
@@ -29,6 +32,8 @@ class Calendar extends lit_1.LitElement {
|
|
|
29
32
|
}
|
|
30
33
|
};
|
|
31
34
|
this.onDayHover = (event) => {
|
|
35
|
+
if (this.displayOnly)
|
|
36
|
+
return;
|
|
32
37
|
const day = event.target.dataset.date;
|
|
33
38
|
if (!day)
|
|
34
39
|
return;
|
|
@@ -59,6 +64,14 @@ class Calendar extends lit_1.LitElement {
|
|
|
59
64
|
}
|
|
60
65
|
return luxon_1.Interval.invalid('Invalid range');
|
|
61
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
|
+
}
|
|
62
75
|
updated(changedProperties) {
|
|
63
76
|
if (changedProperties.has('value') && this.value) {
|
|
64
77
|
super.updateComplete.then(() => {
|
|
@@ -98,6 +111,8 @@ class Calendar extends lit_1.LitElement {
|
|
|
98
111
|
}
|
|
99
112
|
}
|
|
100
113
|
handleKeyDown(event) {
|
|
114
|
+
if (this.displayOnly)
|
|
115
|
+
return;
|
|
101
116
|
const currentDate = this.focusedDate;
|
|
102
117
|
switch (event.key) {
|
|
103
118
|
case 'ArrowLeft':
|
|
@@ -161,7 +176,7 @@ class Calendar extends lit_1.LitElement {
|
|
|
161
176
|
focusDay(date) {
|
|
162
177
|
this.focusedDate = date;
|
|
163
178
|
this.updateComplete.then(() => {
|
|
164
|
-
const dayElement = this.shadowRoot?.querySelector(`.day[data-date="${date.
|
|
179
|
+
const dayElement = (this.shadowRoot?.querySelector(`.day[data-date="${date.toISODate()}"]`));
|
|
165
180
|
if (dayElement) {
|
|
166
181
|
dayElement.focus();
|
|
167
182
|
}
|
|
@@ -205,6 +220,8 @@ class Calendar extends lit_1.LitElement {
|
|
|
205
220
|
return luxon_1.DateTime.local();
|
|
206
221
|
}
|
|
207
222
|
handleDayClick(day) {
|
|
223
|
+
if (this.displayOnly)
|
|
224
|
+
return;
|
|
208
225
|
if (this.isRange()) {
|
|
209
226
|
if (!this.value?.startDate || this.value?.endDate) {
|
|
210
227
|
this.value = { startDate: day.toISODate() };
|
|
@@ -260,6 +277,18 @@ class Calendar extends lit_1.LitElement {
|
|
|
260
277
|
get isSelectingRange() {
|
|
261
278
|
return Boolean(this.isRange() && this.value?.startDate && !this.value?.endDate);
|
|
262
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
|
+
}
|
|
263
292
|
handleToggle(e) {
|
|
264
293
|
const details = e.target;
|
|
265
294
|
if (details.open) {
|
|
@@ -270,48 +299,51 @@ class Calendar extends lit_1.LitElement {
|
|
|
270
299
|
}
|
|
271
300
|
}
|
|
272
301
|
render() {
|
|
273
|
-
const
|
|
274
|
-
const
|
|
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({
|
|
275
305
|
month: 'long',
|
|
276
306
|
year: 'numeric',
|
|
277
307
|
});
|
|
278
308
|
return (0, lit_1.html) `
|
|
279
309
|
<div class="calendar-panel" @keydown=${this.handleKeyDown} role="application" aria-label="${monthYear}">
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
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>`}
|
|
315
347
|
<div class="calendar-grid">
|
|
316
348
|
<table
|
|
317
349
|
role="grid"
|
|
@@ -335,15 +367,15 @@ class Calendar extends lit_1.LitElement {
|
|
|
335
367
|
return (0, lit_1.html) ` <td
|
|
336
368
|
class="${(0, class_map_js_1.classMap)({
|
|
337
369
|
day: true,
|
|
338
|
-
'in-range': this.isInRange(day),
|
|
339
|
-
'start-date': this.isStartDate(day),
|
|
340
|
-
'end-date': this.isEndDate(day),
|
|
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),
|
|
341
373
|
})}"
|
|
342
374
|
@click=${() => this.handleDayClick(day)}
|
|
343
375
|
role="gridcell"
|
|
344
376
|
data-date="${day.toISODate()}"
|
|
345
377
|
aria-label="${day.toLocaleString({ dateStyle: 'long' })}"
|
|
346
|
-
aria-selected="${this.isSelected(day)}"
|
|
378
|
+
aria-selected="${this.isSelected(day) || this.isHighlighted(day)}"
|
|
347
379
|
aria-disabled="${isDisabled}"
|
|
348
380
|
tabindex="-1"
|
|
349
381
|
@mouseenter="${this.onDayHover}"
|
|
@@ -356,32 +388,36 @@ class Calendar extends lit_1.LitElement {
|
|
|
356
388
|
</table>
|
|
357
389
|
</div>
|
|
358
390
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
<
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
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>`}
|
|
385
421
|
</div>
|
|
386
422
|
`;
|
|
387
423
|
}
|
|
@@ -423,6 +459,15 @@ __decorate([
|
|
|
423
459
|
__decorate([
|
|
424
460
|
(0, decorators_js_1.property)({ type: Number, attribute: 'min-days' })
|
|
425
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);
|
|
426
471
|
__decorate([
|
|
427
472
|
(0, decorators_js_1.query)('.calendar-panel')
|
|
428
473
|
], Calendar.prototype, "calendarDiv", void 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TtCalendar.js","sourceRoot":"","sources":["../../../src/TtCalendar.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, LitElement, 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 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 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 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 private focusDay(date: DateTime) {\n this.focusedDate = date;\n this.updateComplete.then(() => {\n const dayElement = <HTMLElement | undefined>this.shadowRoot?.querySelector(`.day[data-date=\"${date.toISO()}\"]`);\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.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 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 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 weeks = this.getDaysInMonth(this.focusedDate);\n const monthYear = this.focusedDate.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 <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),\n 'start-date': this.isStartDate(day),\n 'end-date': this.isEndDate(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)}\"\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 <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` <button @click=${() => this.handleDayClick(this.today)} data-theme=\"secondary\">Today</button> `}\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"]}
|
|
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"]}
|
|
@@ -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;
|
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
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;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { html, LitElement } from 'lit';
|
|
7
|
+
import { html, LitElement, nothing } from 'lit';
|
|
8
8
|
import { property, query, state } from 'lit/decorators.js';
|
|
9
9
|
import { classMap } from 'lit/directives/class-map.js';
|
|
10
10
|
import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
|
|
@@ -17,6 +17,9 @@ export class Calendar extends LitElement {
|
|
|
17
17
|
constructor() {
|
|
18
18
|
super(...arguments);
|
|
19
19
|
this.range = false;
|
|
20
|
+
this.displayOnly = false;
|
|
21
|
+
this.highlightedRanges = [];
|
|
22
|
+
this._parsedHighlights = [];
|
|
20
23
|
this.focusedDate = this.today;
|
|
21
24
|
this.visible = false;
|
|
22
25
|
this.newWeek = () => new Array(7).fill(null);
|
|
@@ -26,6 +29,8 @@ export class Calendar extends LitElement {
|
|
|
26
29
|
}
|
|
27
30
|
};
|
|
28
31
|
this.onDayHover = (event) => {
|
|
32
|
+
if (this.displayOnly)
|
|
33
|
+
return;
|
|
29
34
|
const day = event.target.dataset.date;
|
|
30
35
|
if (!day)
|
|
31
36
|
return;
|
|
@@ -56,6 +61,14 @@ export class Calendar extends LitElement {
|
|
|
56
61
|
}
|
|
57
62
|
return Interval.invalid('Invalid range');
|
|
58
63
|
}
|
|
64
|
+
willUpdate(changedProperties) {
|
|
65
|
+
if (changedProperties.has('highlightedRanges')) {
|
|
66
|
+
this._parsedHighlights = this.highlightedRanges.map((range) => ({
|
|
67
|
+
start: DateTime.fromISO(range.startDate),
|
|
68
|
+
end: DateTime.fromISO(range.endDate),
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
59
72
|
updated(changedProperties) {
|
|
60
73
|
if (changedProperties.has('value') && this.value) {
|
|
61
74
|
super.updateComplete.then(() => {
|
|
@@ -95,6 +108,8 @@ export class Calendar extends LitElement {
|
|
|
95
108
|
}
|
|
96
109
|
}
|
|
97
110
|
handleKeyDown(event) {
|
|
111
|
+
if (this.displayOnly)
|
|
112
|
+
return;
|
|
98
113
|
const currentDate = this.focusedDate;
|
|
99
114
|
switch (event.key) {
|
|
100
115
|
case 'ArrowLeft':
|
|
@@ -158,7 +173,7 @@ export class Calendar extends LitElement {
|
|
|
158
173
|
focusDay(date) {
|
|
159
174
|
this.focusedDate = date;
|
|
160
175
|
this.updateComplete.then(() => {
|
|
161
|
-
const dayElement = this.shadowRoot?.querySelector(`.day[data-date="${date.
|
|
176
|
+
const dayElement = (this.shadowRoot?.querySelector(`.day[data-date="${date.toISODate()}"]`));
|
|
162
177
|
if (dayElement) {
|
|
163
178
|
dayElement.focus();
|
|
164
179
|
}
|
|
@@ -202,6 +217,8 @@ export class Calendar extends LitElement {
|
|
|
202
217
|
return DateTime.local();
|
|
203
218
|
}
|
|
204
219
|
handleDayClick(day) {
|
|
220
|
+
if (this.displayOnly)
|
|
221
|
+
return;
|
|
205
222
|
if (this.isRange()) {
|
|
206
223
|
if (!this.value?.startDate || this.value?.endDate) {
|
|
207
224
|
this.value = { startDate: day.toISODate() };
|
|
@@ -257,6 +274,18 @@ export class Calendar extends LitElement {
|
|
|
257
274
|
get isSelectingRange() {
|
|
258
275
|
return Boolean(this.isRange() && this.value?.startDate && !this.value?.endDate);
|
|
259
276
|
}
|
|
277
|
+
isHighlighted(date) {
|
|
278
|
+
return this._parsedHighlights.some(({ start, end }) => date >= start && date <= end);
|
|
279
|
+
}
|
|
280
|
+
isHighlightedStart(date) {
|
|
281
|
+
return this._parsedHighlights.some(({ start, end }) => date.equals(start) && !start.equals(end));
|
|
282
|
+
}
|
|
283
|
+
isHighlightedEnd(date) {
|
|
284
|
+
return this._parsedHighlights.some(({ start, end }) => date.equals(end) && !start.equals(end));
|
|
285
|
+
}
|
|
286
|
+
isHighlightedInRange(date) {
|
|
287
|
+
return this._parsedHighlights.some(({ start, end }) => date > start && date < end);
|
|
288
|
+
}
|
|
260
289
|
handleToggle(e) {
|
|
261
290
|
const details = e.target;
|
|
262
291
|
if (details.open) {
|
|
@@ -267,48 +296,51 @@ export class Calendar extends LitElement {
|
|
|
267
296
|
}
|
|
268
297
|
}
|
|
269
298
|
render() {
|
|
270
|
-
const
|
|
271
|
-
const
|
|
299
|
+
const displayDate = this.month ? DateTime.fromISO(this.month + '-01') : this.focusedDate;
|
|
300
|
+
const weeks = this.getDaysInMonth(displayDate);
|
|
301
|
+
const monthYear = displayDate.toLocaleString({
|
|
272
302
|
month: 'long',
|
|
273
303
|
year: 'numeric',
|
|
274
304
|
});
|
|
275
305
|
return html `
|
|
276
306
|
<div class="calendar-panel" @keydown=${this.handleKeyDown} role="application" aria-label="${monthYear}">
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
307
|
+
${this.displayOnly
|
|
308
|
+
? nothing
|
|
309
|
+
: html `<div class="calendar-header">
|
|
310
|
+
<button
|
|
311
|
+
@click=${this.previousYear}
|
|
312
|
+
@keydown=${this.handleButtonKeyDown}
|
|
313
|
+
aria-label="Previous year"
|
|
314
|
+
class="compact"
|
|
315
|
+
>
|
|
316
|
+
${unsafeSVG(doubleChevron)}
|
|
317
|
+
</button>
|
|
318
|
+
<button
|
|
319
|
+
@click=${this.previousMonth}
|
|
320
|
+
@keydown="${this.handleButtonKeyDown}"
|
|
321
|
+
aria-label="Previous month"
|
|
322
|
+
class="compact"
|
|
323
|
+
>
|
|
324
|
+
${unsafeSVG(chevron)}
|
|
325
|
+
</button>
|
|
326
|
+
<h2>${monthYear}</h2>
|
|
327
|
+
<button
|
|
328
|
+
@click=${this.nextMonth}
|
|
329
|
+
@keydown="${this.handleButtonKeyDown}"
|
|
330
|
+
aria-label="Next month"
|
|
331
|
+
class="compact right"
|
|
332
|
+
>
|
|
333
|
+
${unsafeSVG(chevron)}
|
|
334
|
+
</button>
|
|
335
|
+
<button
|
|
336
|
+
@click=${this.nextYear}
|
|
337
|
+
@keydown=${this.handleButtonKeyDown}
|
|
338
|
+
aria-label="Next year"
|
|
339
|
+
class="compact right"
|
|
340
|
+
>
|
|
341
|
+
${unsafeSVG(doubleChevron)}
|
|
342
|
+
</button>
|
|
343
|
+
</div>`}
|
|
312
344
|
<div class="calendar-grid">
|
|
313
345
|
<table
|
|
314
346
|
role="grid"
|
|
@@ -332,15 +364,15 @@ export class Calendar extends LitElement {
|
|
|
332
364
|
return html ` <td
|
|
333
365
|
class="${classMap({
|
|
334
366
|
day: true,
|
|
335
|
-
'in-range': this.isInRange(day),
|
|
336
|
-
'start-date': this.isStartDate(day),
|
|
337
|
-
'end-date': this.isEndDate(day),
|
|
367
|
+
'in-range': this.isInRange(day) || this.isHighlightedInRange(day),
|
|
368
|
+
'start-date': this.isStartDate(day) || this.isHighlightedStart(day),
|
|
369
|
+
'end-date': this.isEndDate(day) || this.isHighlightedEnd(day),
|
|
338
370
|
})}"
|
|
339
371
|
@click=${() => this.handleDayClick(day)}
|
|
340
372
|
role="gridcell"
|
|
341
373
|
data-date="${day.toISODate()}"
|
|
342
374
|
aria-label="${day.toLocaleString({ dateStyle: 'long' })}"
|
|
343
|
-
aria-selected="${this.isSelected(day)}"
|
|
375
|
+
aria-selected="${this.isSelected(day) || this.isHighlighted(day)}"
|
|
344
376
|
aria-disabled="${isDisabled}"
|
|
345
377
|
tabindex="-1"
|
|
346
378
|
@mouseenter="${this.onDayHover}"
|
|
@@ -353,32 +385,36 @@ export class Calendar extends LitElement {
|
|
|
353
385
|
</table>
|
|
354
386
|
</div>
|
|
355
387
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
<
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
388
|
+
${this.displayOnly
|
|
389
|
+
? nothing
|
|
390
|
+
: html `<div class="calendar-footer">
|
|
391
|
+
<div class="actions" @keydown="${this.handleButtonKeyDown}">
|
|
392
|
+
${this.isRange()
|
|
393
|
+
? html `
|
|
394
|
+
<button @click=${() => this.handleClearSelection()} data-theme="secondary" id="clear-selection">
|
|
395
|
+
Clear selection
|
|
396
|
+
</button>
|
|
397
|
+
`
|
|
398
|
+
: html `
|
|
399
|
+
<button @click=${() => this.handleDayClick(this.today)} data-theme="secondary">Today</button>
|
|
400
|
+
`}
|
|
401
|
+
</div>
|
|
402
|
+
<div>
|
|
403
|
+
<details @keydown=${this.handleButtonKeyDown} @toggle=${this.handleToggle}>
|
|
404
|
+
<summary>${unsafeSVG(keyboard)} Keyboard commands ${unsafeSVG(chevronDown)}</summary>
|
|
405
|
+
<p>Arrow keys: navigate the calendar</p>
|
|
406
|
+
<p>Enter or Space: select the date</p>
|
|
407
|
+
<p>Escape: close the calendar without selecting a date</p>
|
|
408
|
+
<p>Tab: navigate between the calendar and the presets</p>
|
|
409
|
+
<p>Home: move to first day of week</p>
|
|
410
|
+
<p>End: move to last day of week</p>
|
|
411
|
+
<p>Page Up: move to previous month</p>
|
|
412
|
+
<p>Page Down: move to next month</p>
|
|
413
|
+
<p>Shift + Page Up: move to next year</p>
|
|
414
|
+
<p>Shift + Page Down: move to previous year</p>
|
|
415
|
+
</details>
|
|
416
|
+
</div>
|
|
417
|
+
</div>`}
|
|
382
418
|
</div>
|
|
383
419
|
`;
|
|
384
420
|
}
|
|
@@ -419,6 +455,15 @@ __decorate([
|
|
|
419
455
|
__decorate([
|
|
420
456
|
property({ type: Number, attribute: 'min-days' })
|
|
421
457
|
], Calendar.prototype, "minDays", void 0);
|
|
458
|
+
__decorate([
|
|
459
|
+
property({ type: Boolean, reflect: true, attribute: 'display-only' })
|
|
460
|
+
], Calendar.prototype, "displayOnly", void 0);
|
|
461
|
+
__decorate([
|
|
462
|
+
property({ type: String })
|
|
463
|
+
], Calendar.prototype, "month", void 0);
|
|
464
|
+
__decorate([
|
|
465
|
+
property({ attribute: false })
|
|
466
|
+
], Calendar.prototype, "highlightedRanges", void 0);
|
|
422
467
|
__decorate([
|
|
423
468
|
query('.calendar-panel')
|
|
424
469
|
], Calendar.prototype, "calendarDiv", void 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TtCalendar.js","sourceRoot":"","sources":["../../../src/TtCalendar.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, LitElement, 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 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 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 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 private focusDay(date: DateTime) {\n this.focusedDate = date;\n this.updateComplete.then(() => {\n const dayElement = <HTMLElement | undefined>this.shadowRoot?.querySelector(`.day[data-date=\"${date.toISO()}\"]`);\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.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 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 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 weeks = this.getDaysInMonth(this.focusedDate);\n const monthYear = this.focusedDate.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 <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),\n 'start-date': this.isStartDate(day),\n 'end-date': this.isEndDate(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)}\"\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 <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` <button @click=${() => this.handleDayClick(this.today)} data-theme=\"secondary\">Today</button> `}\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"]}
|
|
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"]}
|
|
@@ -175,6 +175,68 @@ describe('Calendar', () => {
|
|
|
175
175
|
expect(detail.endDate).to.be.undefined;
|
|
176
176
|
});
|
|
177
177
|
});
|
|
178
|
+
describe('display-only mode', () => {
|
|
179
|
+
it('does not render navigation controls when display-only', async () => {
|
|
180
|
+
const el = await fixture(html `<tt-calendar display-only></tt-calendar>`);
|
|
181
|
+
const buttons = el.shadowRoot.querySelectorAll('.calendar-header button');
|
|
182
|
+
expect(buttons.length).to.equal(0);
|
|
183
|
+
});
|
|
184
|
+
it('does not emit date-selection event on click when display-only', async () => {
|
|
185
|
+
const el = await fixture(html `<tt-calendar display-only></tt-calendar>`);
|
|
186
|
+
let eventFired = false;
|
|
187
|
+
el.addEventListener('date-selection', () => {
|
|
188
|
+
eventFired = true;
|
|
189
|
+
});
|
|
190
|
+
const day = el.shadowRoot.querySelector('.day:not([aria-disabled="true"])');
|
|
191
|
+
day?.click();
|
|
192
|
+
await el.updateComplete;
|
|
193
|
+
expect(eventFired).to.be.false;
|
|
194
|
+
});
|
|
195
|
+
it('does not process keyboard events when display-only', async () => {
|
|
196
|
+
const el = await fixture(html `<tt-calendar display-only></tt-calendar>`);
|
|
197
|
+
const initialFocusedDate = el.focusedDate.toISODate();
|
|
198
|
+
const panel = el.shadowRoot.querySelector('.calendar-panel');
|
|
199
|
+
panel.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight', bubbles: true }));
|
|
200
|
+
await el.updateComplete;
|
|
201
|
+
expect(el.focusedDate.toISODate()).to.equal(initialFocusedDate);
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
describe('month property', () => {
|
|
205
|
+
it('displays the specified month when month is set', async () => {
|
|
206
|
+
const el = await fixture(html `<tt-calendar month="2026-06"></tt-calendar>`);
|
|
207
|
+
const header = el.shadowRoot.querySelector('h2');
|
|
208
|
+
expect(header.textContent).to.include('June');
|
|
209
|
+
expect(header.textContent).to.include('2026');
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
describe('highlighted-ranges', () => {
|
|
213
|
+
it('applies aria-selected to dates within highlighted ranges', async () => {
|
|
214
|
+
const el = await fixture(html `<tt-calendar month="2026-03"></tt-calendar>`);
|
|
215
|
+
el.highlightedRanges = [{ startDate: '2026-03-05', endDate: '2026-03-05' }];
|
|
216
|
+
await el.updateComplete;
|
|
217
|
+
const day5 = el.shadowRoot.querySelector('.day[data-date="2026-03-05"]');
|
|
218
|
+
expect(day5?.getAttribute('aria-selected')).to.equal('true');
|
|
219
|
+
});
|
|
220
|
+
it('applies in-range class for multi-day ranges', async () => {
|
|
221
|
+
const el = await fixture(html `<tt-calendar month="2026-03"></tt-calendar>`);
|
|
222
|
+
el.highlightedRanges = [{ startDate: '2026-03-10', endDate: '2026-03-15' }];
|
|
223
|
+
await el.updateComplete;
|
|
224
|
+
const day10 = el.shadowRoot.querySelector('.day[data-date="2026-03-10"]');
|
|
225
|
+
const day12 = el.shadowRoot.querySelector('.day[data-date="2026-03-12"]');
|
|
226
|
+
const day15 = el.shadowRoot.querySelector('.day[data-date="2026-03-15"]');
|
|
227
|
+
expect(day10?.classList.contains('start-date')).to.be.true;
|
|
228
|
+
expect(day12?.classList.contains('in-range')).to.be.true;
|
|
229
|
+
expect(day15?.classList.contains('end-date')).to.be.true;
|
|
230
|
+
});
|
|
231
|
+
it('does not apply in-range for single-date highlights', async () => {
|
|
232
|
+
const el = await fixture(html `<tt-calendar month="2026-03"></tt-calendar>`);
|
|
233
|
+
el.highlightedRanges = [{ startDate: '2026-03-05', endDate: '2026-03-05' }];
|
|
234
|
+
await el.updateComplete;
|
|
235
|
+
const day5 = el.shadowRoot.querySelector('.day[data-date="2026-03-05"]');
|
|
236
|
+
expect(day5?.classList.contains('in-range')).to.be.false;
|
|
237
|
+
expect(day5?.classList.contains('start-date')).to.be.false;
|
|
238
|
+
});
|
|
239
|
+
});
|
|
178
240
|
describe('a11y', () => {
|
|
179
241
|
it('should have proper ARIA attributes', async () => {
|
|
180
242
|
const el = await fixture(html ` <tt-calendar></tt-calendar>`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tt-calendar.test.js","sourceRoot":"","sources":["../../../test/tt-calendar.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { elementUpdated, expect, fixture, html, oneEvent } from '@open-wc/testing';\nimport { DateTime, Settings } from 'luxon';\nimport '../src/tt-calendar.js'; // This handles the registration\nimport { Calendar } from '../src/TtCalendar.js';\n\ndescribe('Calendar', () => {\n describe('initialization', () => {\n const originalNow = DateTime.now().toMillis();\n\n afterEach(() => {\n Settings.defaultZone = 'system';\n Settings.now = () => originalNow;\n });\n\n it('should render with default props', async () => {\n const el = await fixture<Calendar>(html` <tt-calendar></tt-calendar>`);\n expect(el).to.exist;\n expect(el.range).to.be.false;\n expect(el.value).to.be.undefined;\n });\n\n ['Australia/Brisbane', 'America/New_York', 'Europe/London', 'Asia/Tokyo', 'Etc/UTC'].forEach((timezone) => {\n it(`should render the correct days of the week in ${timezone} timezone`, async () => {\n Settings.defaultZone = timezone;\n const now = DateTime.local(2025, 6, 4, 22, 0, 0).toMillis();\n Settings.now = () => now;\n const today = DateTime.now().toISO()!;\n const el = await fixture<Calendar>(html` <tt-calendar value=\"${today}\"></tt-calendar>`);\n\n const sunday = DateTime.fromISO(today).startOf('week').plus({ days: 6 }).toFormat('ccc');\n\n const headers = el.shadowRoot!.querySelectorAll('th');\n expect(headers[0].textContent?.trim()).to.equal(sunday);\n\n const dayRows = el.shadowRoot!.querySelectorAll('tr');\n const secondRowOfDays = dayRows[2].querySelectorAll('td');\n\n expect(secondRowOfDays[0].textContent?.trim()).to.equal('8');\n });\n });\n });\n\n describe('visibility', () => {\n xit('should toggle visibility when calling toggleVisibility', async () => {\n const el = await fixture<Calendar>(html` <tt-calendar></tt-calendar>`);\n\n expect(el).to.be.instanceOf(Calendar);\n\n el.toggleVisibility();\n await elementUpdated(el);\n\n await expect(el.shadowRoot!.querySelector('[part=\"dialog\"]')?.getAttribute('inert')).not.to.exist;\n\n el.toggleVisibility();\n await elementUpdated(el);\n await expect(el.shadowRoot!.querySelector('[part=\"dialog\"]')?.getAttribute('inert')).to.exist;\n });\n\n xit('should close on outside click', async () => {\n const el = await fixture<Calendar>(html` <tt-calendar></tt-calendar>`);\n el.toggleVisibility();\n await elementUpdated(el);\n\n const focusOutEvent = new FocusEvent('focusout', {\n relatedTarget: document.body,\n });\n el.shadowRoot!.querySelector('[part=\"calendar\"]')?.dispatchEvent(focusOutEvent);\n await elementUpdated(el);\n\n await expect(el.shadowRoot!.querySelector('[part=\"calendar\"]')?.getAttribute('inert')).to.exist;\n });\n\n xit('should focus calendar div when opened', async () => {\n const el = await fixture<Calendar>(html` <tt-calendar></tt-calendar>`);\n el.toggleVisibility();\n\n await elementUpdated(el);\n\n const calendar = el.shadowRoot!.querySelector('[part=\"calendar\"]');\n expect(calendar).to.exist;\n expect(el.shadowRoot!.activeElement === calendar).to.be.true;\n });\n });\n\n ['Australia/Brisbane', 'America/New_York', 'Europe/London', 'Asia/Tokyo', 'Etc/UTC'].forEach((timezone) => {\n describe(`single date selection in ${timezone} timezone`, () => {\n const originalNow = DateTime.now().toMillis();\n\n afterEach(() => {\n Settings.defaultZone = 'system';\n Settings.now = () => originalNow;\n });\n\n const selectDay = (day: string, el: HTMLElement): void => {\n if (!el.shadowRoot) {\n throw new Error('Shadow root not found');\n }\n\n const allCells = el.shadowRoot.querySelectorAll('td[role=\"gridcell\"]');\n const dayCell = Array.from(allCells).filter((cell) => cell.textContent?.trim() === day)[0] as HTMLElement;\n dayCell.click();\n };\n\n it('should emit date-selection event when selecting a date', async () => {\n Settings.defaultZone = timezone;\n const el = await fixture<Calendar>(html` <tt-calendar value=\"2025-01-09\"></tt-calendar>`);\n const listener = oneEvent(el, 'date-selection');\n await elementUpdated(el);\n selectDay('4', el);\n\n await elementUpdated(el);\n\n const { detail } = await listener;\n const actual = detail as Date;\n const expected = '2025-01-04';\n expect(actual).to.equal(expected);\n });\n });\n });\n ['Australia/Brisbane', 'America/New_York', 'Europe/London', 'Asia/Tokyo', 'Etc/UTC'].forEach((timezone) => {\n describe('date range selection', () => {\n it(`should emit date-range-selection event when selecting range in ${timezone} timezone`, async () => {\n Settings.defaultZone = timezone;\n Settings.now = () => DateTime.local(2025, 7, 1, 22, 0, 0).toMillis();\n const el = await fixture<Calendar>(html` <tt-calendar range></tt-calendar>`);\n const listener = oneEvent(el, 'date-range-selection');\n\n el.toggleVisibility();\n await elementUpdated(el);\n\n const days = el.shadowRoot!.querySelectorAll('.day');\n const firstDay = days[0] as HTMLElement;\n const lastDay = days[5] as HTMLElement;\n\n firstDay.click();\n lastDay.click();\n\n await elementUpdated(el);\n\n const { detail } = await listener;\n\n expect(detail).to.have.property('startDate');\n expect(detail).to.have.property('endDate');\n\n const { startDate, endDate } = detail;\n const expectedStartDate = '2025-07-01';\n const expectedEndDate = '2025-07-06';\n await expect(startDate).to.equal(expectedStartDate);\n await expect(endDate).to.equal(expectedEndDate);\n });\n\n it('should disable dates before the start of the range when selecting', async () => {\n Settings.defaultZone = timezone;\n const el = await fixture<Calendar>(html` <tt-calendar range></tt-calendar>`);\n el.toggleVisibility();\n await elementUpdated(el);\n\n const days = el.shadowRoot!.querySelectorAll('.day');\n (days[5] as HTMLElement).click();\n await elementUpdated(el);\n\n await expect(days[4].getAttribute('aria-disabled')).to.equal('true');\n });\n\n it('should disable dates before min-date', async () => {\n Settings.defaultZone = timezone;\n Settings.now = () => DateTime.local(2025, 7, 1, 22, 0, 0).toMillis();\n const el = await fixture<Calendar>(html` <tt-calendar min-date=\"2025-07-05\"></tt-calendar>`);\n el.toggleVisibility();\n await elementUpdated(el);\n\n const disabledDate = el.shadowRoot!.querySelector('[data-date=\"2025-07-04\"]') as HTMLElement;\n const enabledDate = el.shadowRoot!.querySelector('[data-date=\"2025-07-05\"]') as HTMLElement;\n\n await expect(disabledDate.getAttribute('aria-disabled')).to.equal('true');\n await expect(enabledDate.getAttribute('aria-disabled')).to.equal('false');\n });\n\n it('should disable dates before max-date', async () => {\n Settings.defaultZone = timezone;\n Settings.now = () => DateTime.local(2025, 7, 1, 22, 0, 0).toMillis();\n const el = await fixture<Calendar>(html` <tt-calendar max-date=\"2025-07-05\"></tt-calendar>`);\n el.toggleVisibility();\n await elementUpdated(el);\n\n const disabledDate = el.shadowRoot!.querySelector('[data-date=\"2025-07-06\"]') as HTMLElement;\n const enabledDate = el.shadowRoot!.querySelector('[data-date=\"2025-07-05\"]') as HTMLElement;\n\n await expect(disabledDate.getAttribute('aria-disabled')).to.equal('true');\n await expect(enabledDate.getAttribute('aria-disabled')).to.equal('false');\n });\n\n it('should disable dates after selected date + max days', async () => {\n Settings.defaultZone = timezone;\n Settings.now = () => DateTime.local(2025, 7, 1, 22, 0, 0).toMillis();\n const el = await fixture<Calendar>(html` <tt-calendar range max-days=\"1\"></tt-calendar>`);\n el.toggleVisibility();\n await elementUpdated(el);\n\n const dateStart = el.shadowRoot!.querySelector('[data-date=\"2025-07-06\"]') as HTMLElement;\n dateStart.click();\n await elementUpdated(el);\n\n const disabledDate = el.shadowRoot!.querySelector('[data-date=\"2025-07-08\"]') as HTMLElement;\n\n await expect(disabledDate.getAttribute('aria-disabled')).to.equal('true');\n });\n });\n });\n\n describe('clear selection', () => {\n it('should clear selection', async () => {\n const el = await fixture<Calendar>(html` <tt-calendar range></tt-calendar>`);\n const listener = oneEvent(el, 'date-range-selection');\n\n el.toggleVisibility();\n await elementUpdated(el);\n\n const clearButton = el.shadowRoot!.querySelector('button#clear-selection') as HTMLElement;\n expect(clearButton).to.exist;\n clearButton.click();\n\n const { detail } = await listener;\n expect(detail.startDate).to.be.undefined;\n expect(detail.endDate).to.be.undefined;\n });\n });\n\n describe('a11y', () => {\n it('should have proper ARIA attributes', async () => {\n const el = await fixture<Calendar>(html` <tt-calendar></tt-calendar>`);\n el.toggleVisibility();\n await elementUpdated(el);\n\n const days = el.shadowRoot!.querySelectorAll('.day');\n days.forEach((day) => {\n expect(day.getAttribute('role')).to.equal('gridcell');\n expect(day.getAttribute('aria-label')).to.exist;\n });\n });\n\n it('should have proper ARIA selected states', async () => {\n const el = await fixture<Calendar>(html` <tt-calendar range></tt-calendar>`);\n el.toggleVisibility();\n await elementUpdated(el);\n\n const firstDay = el.shadowRoot!.querySelector('.day') as HTMLElement;\n firstDay.click();\n\n await elementUpdated(el);\n\n await expect(firstDay?.getAttribute('aria-selected')).to.equal('true');\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"tt-calendar.test.js","sourceRoot":"","sources":["../../../test/tt-calendar.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { elementUpdated, expect, fixture, html, oneEvent } from '@open-wc/testing';\nimport { DateTime, Settings } from 'luxon';\nimport '../src/tt-calendar.js'; // This handles the registration\nimport { Calendar } from '../src/TtCalendar.js';\n\ndescribe('Calendar', () => {\n describe('initialization', () => {\n const originalNow = DateTime.now().toMillis();\n\n afterEach(() => {\n Settings.defaultZone = 'system';\n Settings.now = () => originalNow;\n });\n\n it('should render with default props', async () => {\n const el = await fixture<Calendar>(html` <tt-calendar></tt-calendar>`);\n expect(el).to.exist;\n expect(el.range).to.be.false;\n expect(el.value).to.be.undefined;\n });\n\n ['Australia/Brisbane', 'America/New_York', 'Europe/London', 'Asia/Tokyo', 'Etc/UTC'].forEach((timezone) => {\n it(`should render the correct days of the week in ${timezone} timezone`, async () => {\n Settings.defaultZone = timezone;\n const now = DateTime.local(2025, 6, 4, 22, 0, 0).toMillis();\n Settings.now = () => now;\n const today = DateTime.now().toISO()!;\n const el = await fixture<Calendar>(html` <tt-calendar value=\"${today}\"></tt-calendar>`);\n\n const sunday = DateTime.fromISO(today).startOf('week').plus({ days: 6 }).toFormat('ccc');\n\n const headers = el.shadowRoot!.querySelectorAll('th');\n expect(headers[0].textContent?.trim()).to.equal(sunday);\n\n const dayRows = el.shadowRoot!.querySelectorAll('tr');\n const secondRowOfDays = dayRows[2].querySelectorAll('td');\n\n expect(secondRowOfDays[0].textContent?.trim()).to.equal('8');\n });\n });\n });\n\n describe('visibility', () => {\n xit('should toggle visibility when calling toggleVisibility', async () => {\n const el = await fixture<Calendar>(html` <tt-calendar></tt-calendar>`);\n\n expect(el).to.be.instanceOf(Calendar);\n\n el.toggleVisibility();\n await elementUpdated(el);\n\n await expect(el.shadowRoot!.querySelector('[part=\"dialog\"]')?.getAttribute('inert')).not.to.exist;\n\n el.toggleVisibility();\n await elementUpdated(el);\n await expect(el.shadowRoot!.querySelector('[part=\"dialog\"]')?.getAttribute('inert')).to.exist;\n });\n\n xit('should close on outside click', async () => {\n const el = await fixture<Calendar>(html` <tt-calendar></tt-calendar>`);\n el.toggleVisibility();\n await elementUpdated(el);\n\n const focusOutEvent = new FocusEvent('focusout', {\n relatedTarget: document.body,\n });\n el.shadowRoot!.querySelector('[part=\"calendar\"]')?.dispatchEvent(focusOutEvent);\n await elementUpdated(el);\n\n await expect(el.shadowRoot!.querySelector('[part=\"calendar\"]')?.getAttribute('inert')).to.exist;\n });\n\n xit('should focus calendar div when opened', async () => {\n const el = await fixture<Calendar>(html` <tt-calendar></tt-calendar>`);\n el.toggleVisibility();\n\n await elementUpdated(el);\n\n const calendar = el.shadowRoot!.querySelector('[part=\"calendar\"]');\n expect(calendar).to.exist;\n expect(el.shadowRoot!.activeElement === calendar).to.be.true;\n });\n });\n\n ['Australia/Brisbane', 'America/New_York', 'Europe/London', 'Asia/Tokyo', 'Etc/UTC'].forEach((timezone) => {\n describe(`single date selection in ${timezone} timezone`, () => {\n const originalNow = DateTime.now().toMillis();\n\n afterEach(() => {\n Settings.defaultZone = 'system';\n Settings.now = () => originalNow;\n });\n\n const selectDay = (day: string, el: HTMLElement): void => {\n if (!el.shadowRoot) {\n throw new Error('Shadow root not found');\n }\n\n const allCells = el.shadowRoot.querySelectorAll('td[role=\"gridcell\"]');\n const dayCell = Array.from(allCells).filter((cell) => cell.textContent?.trim() === day)[0] as HTMLElement;\n dayCell.click();\n };\n\n it('should emit date-selection event when selecting a date', async () => {\n Settings.defaultZone = timezone;\n const el = await fixture<Calendar>(html` <tt-calendar value=\"2025-01-09\"></tt-calendar>`);\n const listener = oneEvent(el, 'date-selection');\n await elementUpdated(el);\n selectDay('4', el);\n\n await elementUpdated(el);\n\n const { detail } = await listener;\n const actual = detail as Date;\n const expected = '2025-01-04';\n expect(actual).to.equal(expected);\n });\n });\n });\n ['Australia/Brisbane', 'America/New_York', 'Europe/London', 'Asia/Tokyo', 'Etc/UTC'].forEach((timezone) => {\n describe('date range selection', () => {\n it(`should emit date-range-selection event when selecting range in ${timezone} timezone`, async () => {\n Settings.defaultZone = timezone;\n Settings.now = () => DateTime.local(2025, 7, 1, 22, 0, 0).toMillis();\n const el = await fixture<Calendar>(html` <tt-calendar range></tt-calendar>`);\n const listener = oneEvent(el, 'date-range-selection');\n\n el.toggleVisibility();\n await elementUpdated(el);\n\n const days = el.shadowRoot!.querySelectorAll('.day');\n const firstDay = days[0] as HTMLElement;\n const lastDay = days[5] as HTMLElement;\n\n firstDay.click();\n lastDay.click();\n\n await elementUpdated(el);\n\n const { detail } = await listener;\n\n expect(detail).to.have.property('startDate');\n expect(detail).to.have.property('endDate');\n\n const { startDate, endDate } = detail;\n const expectedStartDate = '2025-07-01';\n const expectedEndDate = '2025-07-06';\n await expect(startDate).to.equal(expectedStartDate);\n await expect(endDate).to.equal(expectedEndDate);\n });\n\n it('should disable dates before the start of the range when selecting', async () => {\n Settings.defaultZone = timezone;\n const el = await fixture<Calendar>(html` <tt-calendar range></tt-calendar>`);\n el.toggleVisibility();\n await elementUpdated(el);\n\n const days = el.shadowRoot!.querySelectorAll('.day');\n (days[5] as HTMLElement).click();\n await elementUpdated(el);\n\n await expect(days[4].getAttribute('aria-disabled')).to.equal('true');\n });\n\n it('should disable dates before min-date', async () => {\n Settings.defaultZone = timezone;\n Settings.now = () => DateTime.local(2025, 7, 1, 22, 0, 0).toMillis();\n const el = await fixture<Calendar>(html` <tt-calendar min-date=\"2025-07-05\"></tt-calendar>`);\n el.toggleVisibility();\n await elementUpdated(el);\n\n const disabledDate = el.shadowRoot!.querySelector('[data-date=\"2025-07-04\"]') as HTMLElement;\n const enabledDate = el.shadowRoot!.querySelector('[data-date=\"2025-07-05\"]') as HTMLElement;\n\n await expect(disabledDate.getAttribute('aria-disabled')).to.equal('true');\n await expect(enabledDate.getAttribute('aria-disabled')).to.equal('false');\n });\n\n it('should disable dates before max-date', async () => {\n Settings.defaultZone = timezone;\n Settings.now = () => DateTime.local(2025, 7, 1, 22, 0, 0).toMillis();\n const el = await fixture<Calendar>(html` <tt-calendar max-date=\"2025-07-05\"></tt-calendar>`);\n el.toggleVisibility();\n await elementUpdated(el);\n\n const disabledDate = el.shadowRoot!.querySelector('[data-date=\"2025-07-06\"]') as HTMLElement;\n const enabledDate = el.shadowRoot!.querySelector('[data-date=\"2025-07-05\"]') as HTMLElement;\n\n await expect(disabledDate.getAttribute('aria-disabled')).to.equal('true');\n await expect(enabledDate.getAttribute('aria-disabled')).to.equal('false');\n });\n\n it('should disable dates after selected date + max days', async () => {\n Settings.defaultZone = timezone;\n Settings.now = () => DateTime.local(2025, 7, 1, 22, 0, 0).toMillis();\n const el = await fixture<Calendar>(html` <tt-calendar range max-days=\"1\"></tt-calendar>`);\n el.toggleVisibility();\n await elementUpdated(el);\n\n const dateStart = el.shadowRoot!.querySelector('[data-date=\"2025-07-06\"]') as HTMLElement;\n dateStart.click();\n await elementUpdated(el);\n\n const disabledDate = el.shadowRoot!.querySelector('[data-date=\"2025-07-08\"]') as HTMLElement;\n\n await expect(disabledDate.getAttribute('aria-disabled')).to.equal('true');\n });\n });\n });\n\n describe('clear selection', () => {\n it('should clear selection', async () => {\n const el = await fixture<Calendar>(html` <tt-calendar range></tt-calendar>`);\n const listener = oneEvent(el, 'date-range-selection');\n\n el.toggleVisibility();\n await elementUpdated(el);\n\n const clearButton = el.shadowRoot!.querySelector('button#clear-selection') as HTMLElement;\n expect(clearButton).to.exist;\n clearButton.click();\n\n const { detail } = await listener;\n expect(detail.startDate).to.be.undefined;\n expect(detail.endDate).to.be.undefined;\n });\n });\n\n describe('display-only mode', () => {\n it('does not render navigation controls when display-only', async () => {\n const el = await fixture<Calendar>(html`<tt-calendar display-only></tt-calendar>`);\n const buttons = el.shadowRoot!.querySelectorAll('.calendar-header button');\n expect(buttons.length).to.equal(0);\n });\n\n it('does not emit date-selection event on click when display-only', async () => {\n const el = await fixture<Calendar>(html`<tt-calendar display-only></tt-calendar>`);\n let eventFired = false;\n el.addEventListener('date-selection', () => {\n eventFired = true;\n });\n\n const day = el.shadowRoot!.querySelector('.day:not([aria-disabled=\"true\"])') as HTMLElement;\n day?.click();\n await el.updateComplete;\n\n expect(eventFired).to.be.false;\n });\n\n it('does not process keyboard events when display-only', async () => {\n const el = await fixture<Calendar>(html`<tt-calendar display-only></tt-calendar>`);\n const initialFocusedDate = (el as any).focusedDate.toISODate();\n\n const panel = el.shadowRoot!.querySelector('.calendar-panel') as HTMLElement;\n panel.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight', bubbles: true }));\n await el.updateComplete;\n\n expect((el as any).focusedDate.toISODate()).to.equal(initialFocusedDate);\n });\n });\n\n describe('month property', () => {\n it('displays the specified month when month is set', async () => {\n const el = await fixture<Calendar>(html`<tt-calendar month=\"2026-06\"></tt-calendar>`);\n const header = el.shadowRoot!.querySelector('h2')!;\n expect(header.textContent).to.include('June');\n expect(header.textContent).to.include('2026');\n });\n });\n\n describe('highlighted-ranges', () => {\n it('applies aria-selected to dates within highlighted ranges', async () => {\n const el = await fixture<Calendar>(html`<tt-calendar month=\"2026-03\"></tt-calendar>`);\n el.highlightedRanges = [{ startDate: '2026-03-05', endDate: '2026-03-05' }];\n await el.updateComplete;\n\n const day5 = el.shadowRoot!.querySelector('.day[data-date=\"2026-03-05\"]');\n expect(day5?.getAttribute('aria-selected')).to.equal('true');\n });\n\n it('applies in-range class for multi-day ranges', async () => {\n const el = await fixture<Calendar>(html`<tt-calendar month=\"2026-03\"></tt-calendar>`);\n el.highlightedRanges = [{ startDate: '2026-03-10', endDate: '2026-03-15' }];\n await el.updateComplete;\n\n const day10 = el.shadowRoot!.querySelector('.day[data-date=\"2026-03-10\"]');\n const day12 = el.shadowRoot!.querySelector('.day[data-date=\"2026-03-12\"]');\n const day15 = el.shadowRoot!.querySelector('.day[data-date=\"2026-03-15\"]');\n\n expect(day10?.classList.contains('start-date')).to.be.true;\n expect(day12?.classList.contains('in-range')).to.be.true;\n expect(day15?.classList.contains('end-date')).to.be.true;\n });\n\n it('does not apply in-range for single-date highlights', async () => {\n const el = await fixture<Calendar>(html`<tt-calendar month=\"2026-03\"></tt-calendar>`);\n el.highlightedRanges = [{ startDate: '2026-03-05', endDate: '2026-03-05' }];\n await el.updateComplete;\n\n const day5 = el.shadowRoot!.querySelector('.day[data-date=\"2026-03-05\"]');\n expect(day5?.classList.contains('in-range')).to.be.false;\n expect(day5?.classList.contains('start-date')).to.be.false;\n });\n });\n\n describe('a11y', () => {\n it('should have proper ARIA attributes', async () => {\n const el = await fixture<Calendar>(html` <tt-calendar></tt-calendar>`);\n el.toggleVisibility();\n await elementUpdated(el);\n\n const days = el.shadowRoot!.querySelectorAll('.day');\n days.forEach((day) => {\n expect(day.getAttribute('role')).to.equal('gridcell');\n expect(day.getAttribute('aria-label')).to.exist;\n });\n });\n\n it('should have proper ARIA selected states', async () => {\n const el = await fixture<Calendar>(html` <tt-calendar range></tt-calendar>`);\n el.toggleVisibility();\n await elementUpdated(el);\n\n const firstDay = el.shadowRoot!.querySelector('.day') as HTMLElement;\n firstDay.click();\n\n await elementUpdated(el);\n\n await expect(firstDay?.getAttribute('aria-selected')).to.equal('true');\n });\n });\n});\n"]}
|