@nomideusz/svelte-calendar 1.3.0 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +164 -91
- package/dist/adapters/mapped.d.ts +7 -7
- package/dist/adapters/mapped.js +5 -2
- package/dist/adapters/memory.d.ts +7 -6
- package/dist/adapters/memory.js +3 -4
- package/dist/adapters/recurring.d.ts +6 -6
- package/dist/adapters/recurring.js +12 -14
- package/dist/calendar/Calendar.svelte +65 -18
- package/dist/calendar/Calendar.svelte.d.ts +1 -1
- package/dist/core/locale.d.ts +5 -0
- package/dist/core/locale.js +68 -17
- package/dist/primitives/DayHeader.svelte +9 -9
- package/dist/primitives/EmptySlot.svelte +6 -6
- package/dist/primitives/EventBlock.svelte +19 -19
- package/dist/primitives/FloatingPanel.svelte +4 -4
- package/dist/primitives/NowIndicator.svelte +5 -5
- package/dist/primitives/TimeGutter.svelte +4 -4
- package/dist/theme/auto.d.ts +5 -0
- package/dist/theme/auto.js +32 -4
- package/dist/views/agenda/AgendaDay.svelte +83 -74
- package/dist/views/agenda/AgendaWeek.svelte +53 -52
- package/dist/views/mobile/MobileDay.svelte +34 -34
- package/dist/views/mobile/MobileWeek.svelte +41 -41
- package/dist/views/month/MonthGrid.svelte +49 -23
- package/dist/views/planner/PlannerScroll.svelte +47 -47
- package/dist/views/planner/PlannerWeek.svelte +101 -73
- package/dist/views/shared/context.svelte.d.ts +2 -0
- package/dist/views/shared/context.svelte.js +1 -0
- package/package.json +1 -1
- package/widget/widget.js +376 -223
|
@@ -10,7 +10,7 @@ import EventContent from "../shared/EventContent.svelte";
|
|
|
10
10
|
import { createClock } from "../../core/clock.svelte.js";
|
|
11
11
|
import { sod, addDaysMs, isAllDay } from "../../core/time.js";
|
|
12
12
|
import { startOfWeek as sowFn } from "../../core/time.js";
|
|
13
|
-
import { fmtTime as _fmtTime, fmtWeekRange, weekdayShort } from "../../core/locale.js";
|
|
13
|
+
import { fmtTime as _fmtTime, fmtDayNum, fmtWeekRange, weekdayShort } from "../../core/locale.js";
|
|
14
14
|
import { dateLong } from "../shared/format.js";
|
|
15
15
|
import { createSwipe } from "./swipe.js";
|
|
16
16
|
let { mondayStart = true, locale, height = null, events = [], style = "", focusDate, oneventclick, selectedEventId = null } = $props();
|
|
@@ -53,7 +53,8 @@ const dayCells = $derived.by(() => {
|
|
|
53
53
|
const jsDay = d.getDay();
|
|
54
54
|
const isoDay = jsDay === 0 ? 7 : jsDay;
|
|
55
55
|
if (hideSet.has(isoDay)) continue;
|
|
56
|
-
|
|
56
|
+
// A dateless weekly template (showDates=false) has no today to mark.
|
|
57
|
+
const isToday = showDates && ms === todayMs;
|
|
57
58
|
const isPast = equalDays ? false : ms < todayMs;
|
|
58
59
|
const isWeekend = jsDay === 0 || jsDay === 6;
|
|
59
60
|
const isDisabled = disabledSet.has(ms);
|
|
@@ -99,7 +100,9 @@ function evTimeLabel(ev) {
|
|
|
99
100
|
/** Visible time on a day row: the start, or "until 01:00" on the day an
|
|
100
101
|
* overnight event runs into. */
|
|
101
102
|
function evRowTime(ev, dayMs) {
|
|
102
|
-
|
|
103
|
+
// A multi-day band says "All day" once, on its first row this week;
|
|
104
|
+
// every row's aria-label still says it.
|
|
105
|
+
if (inAllDayStrip(ev)) return dayCells.find((c) => c.events.includes(ev))?.ms === dayMs ? L.allDay : "";
|
|
103
106
|
if (ev.start.getTime() < dayMs) return `${L.until} ${fmtTime(ev.end)}`;
|
|
104
107
|
return fmtTime(ev.start);
|
|
105
108
|
}
|
|
@@ -204,7 +207,7 @@ function handleDayKeydown(e, dayMs) {
|
|
|
204
207
|
<div class="mw-date">
|
|
205
208
|
<span class="mw-day-name" class:mw-day-name--today={cell.isToday}>{cell.dayName}</span>
|
|
206
209
|
{#if showDates}
|
|
207
|
-
<span class="mw-day-num" class:mw-day-num--today={cell.isToday}>{cell.
|
|
210
|
+
<span class="mw-day-num" class:mw-day-num--today={cell.isToday}>{fmtDayNum(cell.ms, locale)}</span>
|
|
208
211
|
{/if}
|
|
209
212
|
</div>
|
|
210
213
|
|
|
@@ -224,11 +227,11 @@ function handleDayKeydown(e, dayMs) {
|
|
|
224
227
|
class:mw-ev--tentative={ev.status === 'tentative'}
|
|
225
228
|
class:mw-ev--full={ev.status === 'full'}
|
|
226
229
|
class:mw-ev--limited={ev.status === 'limited'}
|
|
227
|
-
style:--ev-color={ev.color ?? 'var(--dt-accent)'}
|
|
230
|
+
style:--ev-color={ev.color ?? (inAllDayStrip(ev) ? 'var(--dt-accent)' : 'var(--dt-event, var(--dt-accent))')}
|
|
228
231
|
onclick={(e) => { e.stopPropagation(); oneventclick?.(ev); }}
|
|
229
232
|
onkeydown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); e.stopPropagation(); oneventclick?.(ev); } }}
|
|
230
233
|
onpointerenter={() => oneventhover?.(ev)}
|
|
231
|
-
aria-label="{ev.title}{statusText(ev)}, {evTimeLabel(ev)}"
|
|
234
|
+
aria-label="{ev.title}{statusText(ev)}, {dateLong(cell.ms, locale)}, {evTimeLabel(ev)}"
|
|
232
235
|
>
|
|
233
236
|
<span class="mw-ev-stripe"></span>
|
|
234
237
|
<div class="mw-ev-body">
|
|
@@ -244,6 +247,7 @@ function handleDayKeydown(e, dayMs) {
|
|
|
244
247
|
type="button"
|
|
245
248
|
class="mw-ev-more"
|
|
246
249
|
aria-expanded={expandedDays.has(cell.ms)}
|
|
250
|
+
aria-label="{expandedDays.has(cell.ms) ? L.showLess : L.nMore(cell.totalCount - MAX_EVENTS)}, {dateLong(cell.ms, locale)}"
|
|
247
251
|
onclick={() => toggleExpand(cell.ms)}
|
|
248
252
|
>
|
|
249
253
|
{expandedDays.has(cell.ms) ? L.showLess : L.nMore(cell.totalCount - MAX_EVENTS)}
|
|
@@ -268,7 +272,7 @@ function handleDayKeydown(e, dayMs) {
|
|
|
268
272
|
user-select: none;
|
|
269
273
|
font-variant-numeric: tabular-nums;
|
|
270
274
|
overflow: hidden;
|
|
271
|
-
background: var(--dt-bg, #
|
|
275
|
+
background: var(--dt-bg, #efebe9);
|
|
272
276
|
-webkit-tap-highlight-color: transparent;
|
|
273
277
|
touch-action: pan-y pinch-zoom;
|
|
274
278
|
}
|
|
@@ -282,7 +286,7 @@ function handleDayKeydown(e, dayMs) {
|
|
|
282
286
|
overscroll-behavior: contain;
|
|
283
287
|
-webkit-overflow-scrolling: touch;
|
|
284
288
|
scrollbar-width: thin;
|
|
285
|
-
scrollbar-color: var(--dt-scrollbar, rgba(
|
|
289
|
+
scrollbar-color: var(--dt-scrollbar, rgba(15, 15, 15, 0.1)) transparent;
|
|
286
290
|
}
|
|
287
291
|
.mw--auto .mw-list { overflow-y: visible; }
|
|
288
292
|
.mw-list--animate {
|
|
@@ -308,34 +312,34 @@ function handleDayKeydown(e, dayMs) {
|
|
|
308
312
|
text-align: left;
|
|
309
313
|
width: 100%;
|
|
310
314
|
-webkit-tap-highlight-color: transparent;
|
|
311
|
-
border-bottom: 1px solid var(--dt-border, rgba(
|
|
315
|
+
border-bottom: 1px solid var(--dt-border, rgba(15, 15, 15, 0.08));
|
|
312
316
|
min-height: 56px;
|
|
313
317
|
}
|
|
314
318
|
.mw-row:last-child {
|
|
315
319
|
border-bottom: none;
|
|
316
320
|
}
|
|
317
321
|
.mw-row:has(.mw-row-target:active) {
|
|
318
|
-
background: var(--dt-hover, rgba(
|
|
322
|
+
background: var(--dt-hover, rgba(15, 15, 15, 0.04));
|
|
319
323
|
}
|
|
320
324
|
.mw-row--today {
|
|
321
|
-
background: color-mix(in srgb, var(--dt-accent, #
|
|
325
|
+
background: color-mix(in srgb, var(--dt-accent, #1d4fd7) 4%, transparent);
|
|
322
326
|
}
|
|
323
327
|
/* Token-based dim (not subtree opacity) so past rows stay legible/tappable */
|
|
324
328
|
.mw-row--past {
|
|
325
|
-
background: color-mix(in srgb, var(--dt-text, rgba(
|
|
329
|
+
background: color-mix(in srgb, var(--dt-text, rgba(15, 15, 15, 0.87)) 3%, transparent);
|
|
326
330
|
}
|
|
327
331
|
.mw-row--past :global(.mw-ev-title),
|
|
328
332
|
.mw-row--past :global(.mw-ev-time),
|
|
329
333
|
.mw-row--past .mw-day-num {
|
|
330
|
-
color: var(--dt-text-2, rgba(
|
|
334
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
331
335
|
}
|
|
332
336
|
.mw-row--disabled {
|
|
333
337
|
background-image: repeating-linear-gradient(
|
|
334
338
|
135deg,
|
|
335
339
|
transparent,
|
|
336
340
|
transparent 6px,
|
|
337
|
-
color-mix(in srgb, var(--dt-text, rgba(
|
|
338
|
-
color-mix(in srgb, var(--dt-text, rgba(
|
|
341
|
+
color-mix(in srgb, var(--dt-text, rgba(15, 15, 15, 0.87)) 4%, transparent) 6px,
|
|
342
|
+
color-mix(in srgb, var(--dt-text, rgba(15, 15, 15, 0.87)) 4%, transparent) 12px
|
|
339
343
|
);
|
|
340
344
|
}
|
|
341
345
|
.mw-row-target {
|
|
@@ -353,7 +357,7 @@ function handleDayKeydown(e, dayMs) {
|
|
|
353
357
|
}
|
|
354
358
|
.mw-row-target:focus-visible {
|
|
355
359
|
outline: none;
|
|
356
|
-
box-shadow: inset 0 0 0 2px var(--dt-
|
|
360
|
+
box-shadow: inset 0 0 0 2px var(--dt-text, #0f0f0f);
|
|
357
361
|
}
|
|
358
362
|
|
|
359
363
|
/* ─── Date column ────────────────────────────────── */
|
|
@@ -373,10 +377,10 @@ function handleDayKeydown(e, dayMs) {
|
|
|
373
377
|
font: 500 12px/1 var(--dt-sans, system-ui, sans-serif);
|
|
374
378
|
letter-spacing: 0.08em;
|
|
375
379
|
text-transform: uppercase;
|
|
376
|
-
color: var(--dt-text-2, rgba(
|
|
380
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
377
381
|
}
|
|
378
382
|
.mw-day-name--today {
|
|
379
|
-
color: var(--dt-accent, #
|
|
383
|
+
color: var(--dt-accent, #1d4fd7);
|
|
380
384
|
}
|
|
381
385
|
|
|
382
386
|
/* The date is the typography: large and regular, narrowed like the planner's */
|
|
@@ -385,10 +389,10 @@ function handleDayKeydown(e, dayMs) {
|
|
|
385
389
|
font-stretch: 90%;
|
|
386
390
|
font-variant-numeric: tabular-nums;
|
|
387
391
|
letter-spacing: -0.02em;
|
|
388
|
-
color: var(--dt-text, rgba(
|
|
392
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
389
393
|
}
|
|
390
394
|
.mw-day-num--today {
|
|
391
|
-
color: var(--dt-accent, #
|
|
395
|
+
color: var(--dt-accent, #1d4fd7);
|
|
392
396
|
}
|
|
393
397
|
|
|
394
398
|
/* ─── Events column ──────────────────────────────── */
|
|
@@ -407,7 +411,7 @@ function handleDayKeydown(e, dayMs) {
|
|
|
407
411
|
|
|
408
412
|
.mw-empty {
|
|
409
413
|
font: 400 13px/1 var(--dt-sans, system-ui, sans-serif);
|
|
410
|
-
color: var(--dt-text-2, rgba(
|
|
414
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
411
415
|
}
|
|
412
416
|
|
|
413
417
|
/* ─── Event chip ─────────────────────────────────── */
|
|
@@ -423,20 +427,20 @@ function handleDayKeydown(e, dayMs) {
|
|
|
423
427
|
transition: background 120ms;
|
|
424
428
|
-webkit-tap-highlight-color: transparent;
|
|
425
429
|
border: none;
|
|
426
|
-
border-bottom: 1px solid var(--dt-border, rgba(
|
|
430
|
+
border-bottom: 1px solid var(--dt-border, rgba(15, 15, 15, 0.3));
|
|
427
431
|
text-align: left;
|
|
428
432
|
padding: 0;
|
|
429
433
|
pointer-events: auto;
|
|
430
434
|
}
|
|
431
435
|
.mw-ev:hover,
|
|
432
436
|
.mw-ev:active {
|
|
433
|
-
background: var(--dt-hover, rgba(
|
|
437
|
+
background: var(--dt-hover, rgba(15, 15, 15, 0.04));
|
|
434
438
|
}
|
|
435
439
|
.mw-ev--selected {
|
|
436
440
|
box-shadow: inset 0 0 0 1px var(--ev-color);
|
|
437
441
|
}
|
|
438
442
|
.mw-ev--current {
|
|
439
|
-
background: var(--dt-accent-dim, rgba(
|
|
443
|
+
background: var(--dt-accent-dim, rgba(29, 79, 215, 0.12));
|
|
440
444
|
}
|
|
441
445
|
/* All day: a solid band on the event colour, no tint. */
|
|
442
446
|
.mw-ev--allday {
|
|
@@ -460,14 +464,14 @@ function handleDayKeydown(e, dayMs) {
|
|
|
460
464
|
limited one is set in grey with a dashed bar — never a bare opacity. */
|
|
461
465
|
.mw-ev--cancelled .mw-ev-title {
|
|
462
466
|
text-decoration: line-through;
|
|
463
|
-
color: var(--dt-text-2, rgba(
|
|
467
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
464
468
|
}
|
|
465
469
|
.mw-ev--cancelled .mw-ev-stripe {
|
|
466
470
|
opacity: 0.45; /* decorative bar only */
|
|
467
471
|
}
|
|
468
472
|
.mw-ev--tentative .mw-ev-title,
|
|
469
473
|
.mw-ev--full .mw-ev-title {
|
|
470
|
-
color: var(--dt-text-2, rgba(
|
|
474
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
471
475
|
}
|
|
472
476
|
.mw-ev--tentative .mw-ev-stripe,
|
|
473
477
|
.mw-ev--limited .mw-ev-stripe {
|
|
@@ -500,7 +504,7 @@ function handleDayKeydown(e, dayMs) {
|
|
|
500
504
|
|
|
501
505
|
.mw-ev-title {
|
|
502
506
|
font: 500 15px/1.25 var(--dt-sans, system-ui, sans-serif);
|
|
503
|
-
color: var(--dt-text, rgba(
|
|
507
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
504
508
|
white-space: nowrap;
|
|
505
509
|
overflow: hidden;
|
|
506
510
|
text-overflow: ellipsis;
|
|
@@ -511,14 +515,14 @@ function handleDayKeydown(e, dayMs) {
|
|
|
511
515
|
.mw-ev-time {
|
|
512
516
|
font: 400 14px/1 var(--dt-sans, system-ui, sans-serif);
|
|
513
517
|
font-variant-numeric: tabular-nums;
|
|
514
|
-
color: var(--dt-text, rgba(
|
|
518
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
515
519
|
white-space: nowrap;
|
|
516
520
|
flex-shrink: 0;
|
|
517
521
|
}
|
|
518
522
|
|
|
519
523
|
.mw-ev-more {
|
|
520
524
|
font: 400 12.5px/1 var(--dt-sans, system-ui, sans-serif);
|
|
521
|
-
color: var(--dt-text-2, rgba(
|
|
525
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
522
526
|
padding: 2px 4px;
|
|
523
527
|
min-height: 32px;
|
|
524
528
|
border: none;
|
|
@@ -530,25 +534,21 @@ function handleDayKeydown(e, dayMs) {
|
|
|
530
534
|
pointer-events: auto;
|
|
531
535
|
-webkit-tap-highlight-color: transparent;
|
|
532
536
|
}
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
right: 0;
|
|
539
|
-
top: 50%;
|
|
540
|
-
transform: translateY(-50%);
|
|
541
|
-
height: 44px;
|
|
537
|
+
@media (pointer: coarse) {
|
|
538
|
+
.mw-ev-more {
|
|
539
|
+
min-height: 44px;
|
|
540
|
+
min-width: 44px;
|
|
541
|
+
}
|
|
542
542
|
}
|
|
543
543
|
.mw-ev-more:focus-visible {
|
|
544
544
|
outline: none;
|
|
545
|
-
box-shadow: 0 0 0 2px var(--dt-
|
|
545
|
+
box-shadow: 0 0 0 2px var(--dt-text, #0f0f0f);
|
|
546
546
|
}
|
|
547
547
|
|
|
548
548
|
/* ─── Chevron ────────────────────────────────────── */
|
|
549
549
|
.mw-chevron {
|
|
550
550
|
flex-shrink: 0;
|
|
551
|
-
color: var(--dt-text-3, rgba(
|
|
551
|
+
color: var(--dt-text-3, rgba(15, 15, 15, 0.38));
|
|
552
552
|
position: relative;
|
|
553
553
|
z-index: 1;
|
|
554
554
|
pointer-events: none;
|
|
@@ -557,6 +557,6 @@ function handleDayKeydown(e, dayMs) {
|
|
|
557
557
|
/* ─── Focus ──────────────────────────────────────── */
|
|
558
558
|
.mw-ev:focus-visible {
|
|
559
559
|
outline: none;
|
|
560
|
-
box-shadow: 0 0 0 2px var(--dt-accent, #
|
|
560
|
+
box-shadow: 0 0 0 2px var(--dt-accent, #1d4fd7);
|
|
561
561
|
}
|
|
562
562
|
</style>
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
<script lang="ts">import { useCalendarContext } from "../shared/context.svelte.js";
|
|
10
10
|
import { createClock } from "../../core/clock.svelte.js";
|
|
11
11
|
import { DAY_MS, sod, addDaysMs, isAllDay } from "../../core/time.js";
|
|
12
|
-
import { fmtTime, weekdayShort } from "../../core/locale.js";
|
|
12
|
+
import { fmtTime, fmtDayNum, weekdayShort } from "../../core/locale.js";
|
|
13
|
+
import { dateLong } from "../shared/format.js";
|
|
13
14
|
let { events = [], style = "", height = null, locale, focusDate, oneventclick, selectedEventId = null } = $props();
|
|
14
15
|
const ctx = useCalendarContext();
|
|
15
16
|
const L = $derived(ctx.labels);
|
|
@@ -139,11 +140,18 @@ function cellKeydown(e, cell) {
|
|
|
139
140
|
case " ":
|
|
140
141
|
if (!cell.isDisabled) {
|
|
141
142
|
e.preventDefault();
|
|
142
|
-
|
|
143
|
+
activateCell(cell);
|
|
143
144
|
}
|
|
144
145
|
break;
|
|
145
146
|
}
|
|
146
147
|
}
|
|
148
|
+
/** The cell's own action: drill into the day; on phones (dots, no
|
|
149
|
+
* ondayclick) the whole cell opens its overflow instead of a tiny "+N". */
|
|
150
|
+
function activateCell(cell) {
|
|
151
|
+
if (cell.isDisabled) return;
|
|
152
|
+
if (ondayclick) ondayclick(cell.date);
|
|
153
|
+
else if (dotsMode && cell.overflow > 0) expandedMs = expandedMs === cell.ms ? null : cell.ms;
|
|
154
|
+
}
|
|
147
155
|
function overflowClick(e, cell) {
|
|
148
156
|
e.stopPropagation();
|
|
149
157
|
if (ondayclick) ondayclick(cell.date);
|
|
@@ -236,18 +244,25 @@ function chipTime(e) {
|
|
|
236
244
|
aria-current={cell.isToday ? 'date' : undefined}
|
|
237
245
|
data-ms={cell.ms}
|
|
238
246
|
tabindex={isFocusable(cell) ? (cell.ms === rovingMs ? 0 : -1) : undefined}
|
|
239
|
-
onclick={() =>
|
|
240
|
-
if (!cell.isDisabled) ondayclick?.(cell.date);
|
|
241
|
-
}}
|
|
247
|
+
onclick={() => activateCell(cell)}
|
|
242
248
|
onfocusin={() => (focusMs = cell.ms)}
|
|
243
249
|
onkeydown={(e) => cellKeydown(e, cell)}
|
|
244
250
|
>
|
|
245
251
|
<span class="mg-daynum" class:mg-daynum--today={cell.isToday}>
|
|
246
|
-
{cell.
|
|
252
|
+
{fmtDayNum(cell.ms, locale)}
|
|
247
253
|
</span>
|
|
248
|
-
|
|
254
|
+
<!-- Phones: dots are a picture of the day; the cell (its label counts
|
|
255
|
+
the events) is the one tap and tab target. -->
|
|
256
|
+
<div class="mg-chips" aria-hidden={dotsMode || undefined}>
|
|
249
257
|
{#each expandedMs === cell.ms ? cell.all : cell.chips as ev (ev.id + cell.ms)}
|
|
250
|
-
{#if
|
|
258
|
+
{#if dotsMode}
|
|
259
|
+
<span
|
|
260
|
+
class="mg-chip"
|
|
261
|
+
class:mg-chip--selected={ev.id === selectedEventId}
|
|
262
|
+
class:mg-chip--cancelled={ev.status === 'cancelled'}
|
|
263
|
+
style:--mg-chip-color={ev.color ?? (isAllDay(ev) ? 'var(--dt-accent)' : 'var(--dt-event, var(--dt-accent))')}
|
|
264
|
+
><span class="mg-chip-dot"></span></span>
|
|
265
|
+
{:else if eventSnippet}
|
|
251
266
|
<button
|
|
252
267
|
type="button"
|
|
253
268
|
class="mg-chip mg-chip--custom"
|
|
@@ -266,9 +281,9 @@ function chipTime(e) {
|
|
|
266
281
|
class="mg-chip"
|
|
267
282
|
class:mg-chip--selected={ev.id === selectedEventId}
|
|
268
283
|
class:mg-chip--cancelled={ev.status === 'cancelled'}
|
|
269
|
-
style:--mg-chip-color={ev.color ?? 'var(--dt-accent)'}
|
|
284
|
+
style:--mg-chip-color={ev.color ?? (isAllDay(ev) ? 'var(--dt-accent)' : 'var(--dt-event, var(--dt-accent))')}
|
|
270
285
|
title={ev.title}
|
|
271
|
-
aria-label="{ev.title}{chipTime(ev) ? `, ${chipTime(ev)}` : ''}"
|
|
286
|
+
aria-label="{ev.title}, {dateLong(cell.ms, locale)}{chipTime(ev) ? `, ${chipTime(ev)}` : ''}"
|
|
272
287
|
onclick={(e) => {
|
|
273
288
|
e.stopPropagation();
|
|
274
289
|
oneventclick?.(ev, e.currentTarget.getBoundingClientRect());
|
|
@@ -281,15 +296,19 @@ function chipTime(e) {
|
|
|
281
296
|
</button>
|
|
282
297
|
{/if}
|
|
283
298
|
{/each}
|
|
284
|
-
{#if
|
|
299
|
+
{#if dotsMode}
|
|
300
|
+
{#if cell.overflow > 0 && expandedMs !== cell.ms}
|
|
301
|
+
<span class="mg-more">+{cell.overflow}</span>
|
|
302
|
+
{/if}
|
|
303
|
+
{:else if cell.overflow > 0 && expandedMs !== cell.ms}
|
|
285
304
|
<button
|
|
286
305
|
type="button"
|
|
287
306
|
class="mg-more"
|
|
288
307
|
aria-expanded={ondayclick ? undefined : false}
|
|
289
|
-
aria-label={L.nMore(cell.overflow)}
|
|
308
|
+
aria-label="{L.nMore(cell.overflow)}, {dateLong(cell.ms, locale)}"
|
|
290
309
|
onclick={(e) => overflowClick(e, cell)}
|
|
291
310
|
>
|
|
292
|
-
{
|
|
311
|
+
{L.nMore(cell.overflow)}
|
|
293
312
|
</button>
|
|
294
313
|
{:else if expandedMs === cell.ms}
|
|
295
314
|
<button
|
|
@@ -338,7 +357,7 @@ function chipTime(e) {
|
|
|
338
357
|
font-variant-numeric: tabular-nums;
|
|
339
358
|
text-transform: uppercase;
|
|
340
359
|
letter-spacing: 0.08em;
|
|
341
|
-
color: var(--dt-text-2, rgba(
|
|
360
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.66));
|
|
342
361
|
}
|
|
343
362
|
|
|
344
363
|
.mg-body {
|
|
@@ -372,7 +391,7 @@ function chipTime(e) {
|
|
|
372
391
|
border-right: none;
|
|
373
392
|
}
|
|
374
393
|
.mg-cell--weekend {
|
|
375
|
-
background: var(--dt-weekend-bg, rgba(
|
|
394
|
+
background: var(--dt-weekend-bg, rgba(15, 15, 15, 0.02));
|
|
376
395
|
}
|
|
377
396
|
/* Dim only the day number for adjacent-month cells — their events stay
|
|
378
397
|
legible. text-2, not text-3: a 22px numeral still needs 4.5:1. */
|
|
@@ -380,7 +399,7 @@ function chipTime(e) {
|
|
|
380
399
|
background: var(--dt-surface, transparent);
|
|
381
400
|
}
|
|
382
401
|
.mg-cell--out .mg-daynum {
|
|
383
|
-
color: var(--dt-text-2, rgba(
|
|
402
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.66));
|
|
384
403
|
}
|
|
385
404
|
.mg-cell--today {
|
|
386
405
|
background: var(--dt-today-bg);
|
|
@@ -396,10 +415,10 @@ function chipTime(e) {
|
|
|
396
415
|
cursor: pointer;
|
|
397
416
|
}
|
|
398
417
|
.mg-cell--clickable:hover {
|
|
399
|
-
background: var(--dt-hover, rgba(
|
|
418
|
+
background: var(--dt-hover, rgba(15, 15, 15, 0.04));
|
|
400
419
|
}
|
|
401
420
|
.mg-cell:focus-visible {
|
|
402
|
-
outline: 2px solid var(--dt-
|
|
421
|
+
outline: 2px solid var(--dt-text, #0f0f0f);
|
|
403
422
|
outline-offset: -2px;
|
|
404
423
|
}
|
|
405
424
|
|
|
@@ -446,10 +465,10 @@ function chipTime(e) {
|
|
|
446
465
|
text-align: left;
|
|
447
466
|
}
|
|
448
467
|
.mg-chip:hover {
|
|
449
|
-
background: var(--dt-hover, rgba(
|
|
468
|
+
background: var(--dt-hover, rgba(15, 15, 15, 0.04));
|
|
450
469
|
}
|
|
451
470
|
.mg-chip:focus-visible {
|
|
452
|
-
box-shadow: 0 0 0 2px var(--dt-accent, #
|
|
471
|
+
box-shadow: 0 0 0 2px var(--dt-accent, #1d4fd7);
|
|
453
472
|
outline: none;
|
|
454
473
|
}
|
|
455
474
|
.mg-chip--selected {
|
|
@@ -493,11 +512,11 @@ function chipTime(e) {
|
|
|
493
512
|
cursor: pointer;
|
|
494
513
|
}
|
|
495
514
|
.mg-more:hover {
|
|
496
|
-
background: var(--dt-hover, rgba(
|
|
515
|
+
background: var(--dt-hover, rgba(15, 15, 15, 0.04));
|
|
497
516
|
color: var(--dt-text);
|
|
498
517
|
}
|
|
499
518
|
.mg-more:focus-visible {
|
|
500
|
-
box-shadow: 0 0 0 2px var(--dt-
|
|
519
|
+
box-shadow: 0 0 0 2px var(--dt-text, #0f0f0f);
|
|
501
520
|
outline: none;
|
|
502
521
|
}
|
|
503
522
|
|
|
@@ -518,13 +537,20 @@ function chipTime(e) {
|
|
|
518
537
|
/* ── Dots mode (mobile) ─────────────────────────────
|
|
519
538
|
Cells are too narrow for text chips, so events render as colored
|
|
520
539
|
dots in a wrapping row. The cell itself stays the tap target
|
|
521
|
-
(day drill-down); dots
|
|
540
|
+
(day drill-down) and its label counts the events; dots are aria-hidden. */
|
|
522
541
|
.mg--dots .mg-chips {
|
|
523
542
|
flex-direction: row;
|
|
524
543
|
flex-wrap: wrap;
|
|
525
544
|
align-items: center;
|
|
526
545
|
gap: 3px;
|
|
527
546
|
}
|
|
547
|
+
/* The cell is the target: at least a 44px tap, dots never take the hit. */
|
|
548
|
+
.mg--dots .mg-cell {
|
|
549
|
+
min-height: 44px;
|
|
550
|
+
}
|
|
551
|
+
.mg--dots .mg-chips {
|
|
552
|
+
pointer-events: none;
|
|
553
|
+
}
|
|
528
554
|
.mg--dots .mg-chip {
|
|
529
555
|
padding: 3px;
|
|
530
556
|
min-height: 0;
|