@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
|
@@ -21,7 +21,7 @@ import { createClock } from "../../core/clock.svelte.js";
|
|
|
21
21
|
import { fitParts } from "../../text-fit.js";
|
|
22
22
|
import { HOUR_MS, sod, addDaysMs, diffDays } from "../../core/time.js";
|
|
23
23
|
import { startOfWeek as sowFn, isAllDay, segmentForDay } from "../../core/time.js";
|
|
24
|
-
import { fmtHParts, fmtTime, fmtDuration, fmtWeekRange, weekdayShort, weekdayLong } from "../../core/locale.js";
|
|
24
|
+
import { fmtHParts, fmtTime, fmtDayNum, fmtDuration, fmtWeekRange, weekdayShort, weekdayLong } from "../../core/locale.js";
|
|
25
25
|
import { dateLong } from "../shared/format.js";
|
|
26
26
|
let { mode = "week", mondayStart = true, locale, height = 520, events = [], style = "", focusDate, oneventclick, oneventcreate, onexternaldrop, selectedEventId = null, readOnly = false, visibleHours } = $props();
|
|
27
27
|
// ── Context ────────────────────────────────────────
|
|
@@ -123,6 +123,7 @@ const dayCols = $derived.by(() => {
|
|
|
123
123
|
cols.push({
|
|
124
124
|
ms,
|
|
125
125
|
isToday: ms === todayMs,
|
|
126
|
+
markToday: showDates && ms === todayMs,
|
|
126
127
|
isPast: equalDays ? false : ms < todayMs,
|
|
127
128
|
isWeekend: dow === 0 || dow === 6,
|
|
128
129
|
isDisabled: disabledSet.has(ms),
|
|
@@ -302,8 +303,12 @@ const weekIsEmpty = $derived(!events.some((ev) => ev.start.getTime() < weekEndMs
|
|
|
302
303
|
// Week with today → current time minus ~1h of context; otherwise the
|
|
303
304
|
// visibleHours start or 08:00, whichever is later. Lands on a whole hour,
|
|
304
305
|
// with room for its label (centred on the line) below the sticky top.
|
|
306
|
+
// An event running across that hour line would be sliced under the sticky
|
|
307
|
+
// top, so the scroll starts at that event's hour instead.
|
|
305
308
|
$effect(() => {
|
|
306
309
|
void weekStartMs;
|
|
310
|
+
void startHour;
|
|
311
|
+
void endHour;
|
|
307
312
|
const el = scrollEl;
|
|
308
313
|
if (!el) return;
|
|
309
314
|
untrack(() => {
|
|
@@ -314,7 +319,26 @@ $effect(() => {
|
|
|
314
319
|
} else {
|
|
315
320
|
targetHour = Math.max(startHour, Math.min(8, endHour - 1));
|
|
316
321
|
}
|
|
317
|
-
|
|
322
|
+
let hour = Math.floor(targetHour);
|
|
323
|
+
// Moving up can slice an earlier event on another day, so repeat
|
|
324
|
+
// until no block crosses the line.
|
|
325
|
+
// ponytail: looks back at most 2 h, so a long block can't drag the view to dawn.
|
|
326
|
+
const floorY = (hour - 2 - startHour) * HOUR_H;
|
|
327
|
+
for (let moved = true; moved;) {
|
|
328
|
+
moved = false;
|
|
329
|
+
const line = (hour - startHour) * HOUR_H;
|
|
330
|
+
for (const day of layoutByDay.values()) {
|
|
331
|
+
for (const p of day) {
|
|
332
|
+
if (p.top < line && p.top + p.height > line && p.top >= floorY) {
|
|
333
|
+
hour = Math.floor(startHour + p.top / HOUR_H);
|
|
334
|
+
moved = true;
|
|
335
|
+
break;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
if (moved) break;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
el.scrollTop = Math.max(0, (hour - startHour) * HOUR_H - LABEL_ROOM);
|
|
318
342
|
});
|
|
319
343
|
});
|
|
320
344
|
// ── Pointer coalescing ─────────────────────────────
|
|
@@ -390,11 +414,12 @@ function clampToDayBand(ms, dayMs) {
|
|
|
390
414
|
return Math.max(atHour(dayMs, startHour), Math.min(atHour(dayMs, endHour), ms));
|
|
391
415
|
}
|
|
392
416
|
// ── Blocked slot helpers ───────────────────────────
|
|
417
|
+
/** The blocked slot covering `hour` on the day, if any (truthy = blocked). */
|
|
393
418
|
function isBlockedAt(dayMs, hour) {
|
|
394
|
-
if (!blockedSlots?.length) return
|
|
419
|
+
if (!blockedSlots?.length) return undefined;
|
|
395
420
|
const jsDay = new Date(dayMs).getDay();
|
|
396
421
|
const isoDay = jsDay === 0 ? 7 : jsDay;
|
|
397
|
-
return blockedSlots.
|
|
422
|
+
return blockedSlots.find((slot) => {
|
|
398
423
|
if (slot.day && slot.day !== isoDay) return false;
|
|
399
424
|
return hour >= slot.start && hour < slot.end;
|
|
400
425
|
});
|
|
@@ -641,11 +666,14 @@ function onColKeydown(e, i) {
|
|
|
641
666
|
const day = dayCols[i];
|
|
642
667
|
if (e.key === "Enter" || e.key === " ") {
|
|
643
668
|
e.preventDefault();
|
|
644
|
-
if (!oneventcreate || readOnly
|
|
669
|
+
if (!oneventcreate || readOnly) return;
|
|
670
|
+
// Say why nothing was created, through the calendar's status line.
|
|
671
|
+
if (day.isDisabled) return ctx.announce(`${dateLong(day.ms, locale)}, ${L.unavailable}`);
|
|
645
672
|
const step = Math.max(1, ctx.snapInterval) / 60;
|
|
646
673
|
const want = day.isToday ? snapHour(nowFracHour, "floor") + step : 9;
|
|
647
674
|
const hour = Math.min(Math.max(want, startHour), endHour - step);
|
|
648
|
-
|
|
675
|
+
const slot = isBlockedAt(day.ms, hour);
|
|
676
|
+
if (slot) return ctx.announce(`${slot.label || L.unavailable}, ${blockedRangeLabel(day.ms, slot.start, slot.end)}`);
|
|
649
677
|
const startMs = atHour(day.ms, hour);
|
|
650
678
|
oneventcreate({
|
|
651
679
|
start: new Date(startMs),
|
|
@@ -915,12 +943,12 @@ function onWindowKeydown(e) {
|
|
|
915
943
|
{#each dayCols as day (day.ms)}
|
|
916
944
|
<div
|
|
917
945
|
class="tw-hd"
|
|
918
|
-
class:tw-hd--today={day.
|
|
919
|
-
aria-current={day.
|
|
946
|
+
class:tw-hd--today={day.markToday}
|
|
947
|
+
aria-current={day.markToday ? 'date' : undefined}
|
|
920
948
|
>
|
|
921
949
|
<span class="tw-hd-wd">{singleDay ? weekdayLong(day.ms, locale) : weekdayShort(day.ms, locale)}</span>
|
|
922
950
|
{#if showDates}
|
|
923
|
-
<span class="tw-hd-num" class:tw-hd-num--today={day.
|
|
951
|
+
<span class="tw-hd-num" class:tw-hd-num--today={day.markToday}>{fmtDayNum(day.ms, locale)}</span>
|
|
924
952
|
{/if}
|
|
925
953
|
{#if dayHeaderSnippet}
|
|
926
954
|
<div class="tw-hd-custom">
|
|
@@ -941,7 +969,7 @@ function onWindowKeydown(e) {
|
|
|
941
969
|
{@const segs = allDayByDay.get(day.ms) ?? []}
|
|
942
970
|
{@const isExpanded = adExpanded[day.ms] ?? false}
|
|
943
971
|
{@const shown = isExpanded ? segs : segs.slice(0, ALLDAY_MAX)}
|
|
944
|
-
<div class="tw-ad-cell" class:tw-ad-cell--today={day.
|
|
972
|
+
<div class="tw-ad-cell" class:tw-ad-cell--today={day.markToday}>
|
|
945
973
|
{#each shown as seg (seg.ev.id)}
|
|
946
974
|
{@render allDayChip(seg)}
|
|
947
975
|
{/each}
|
|
@@ -1014,14 +1042,14 @@ function onWindowKeydown(e) {
|
|
|
1014
1042
|
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
|
1015
1043
|
<div
|
|
1016
1044
|
class="tw-col"
|
|
1017
|
-
class:tw-col--today={day.
|
|
1045
|
+
class:tw-col--today={day.markToday}
|
|
1018
1046
|
class:tw-col--past={day.isPast}
|
|
1019
1047
|
class:tw-col--weekend={day.isWeekend}
|
|
1020
1048
|
class:tw-col--disabled={day.isDisabled}
|
|
1021
1049
|
data-day={day.ms}
|
|
1022
1050
|
role={colsCreate ? 'group' : undefined}
|
|
1023
|
-
aria-label={colsCreate ? `${dateLong(day.ms, locale)}, ${L.createEvent}` : undefined}
|
|
1024
|
-
aria-keyshortcuts={colsCreate ? 'Enter' : undefined}
|
|
1051
|
+
aria-label={colsCreate ? `${dateLong(day.ms, locale)}, ${day.isDisabled ? L.unavailable : L.createEvent}` : undefined}
|
|
1052
|
+
aria-keyshortcuts={colsCreate && !day.isDisabled ? 'Enter' : undefined}
|
|
1025
1053
|
tabindex={colsCreate ? (day.ms === tabbableColMs ? 0 : -1) : undefined}
|
|
1026
1054
|
onfocusin={() => (focusedColMs = day.ms)}
|
|
1027
1055
|
onkeydown={colsCreate ? (e) => onColKeydown(e, di) : undefined}
|
|
@@ -1125,8 +1153,8 @@ function onWindowKeydown(e) {
|
|
|
1125
1153
|
style:top="{ghost.top}px"
|
|
1126
1154
|
style:height="{ghost.height}px"
|
|
1127
1155
|
style:--ev-color={ghost.create
|
|
1128
|
-
? 'var(--dt-accent, #
|
|
1129
|
-
: (movingEvent?.color ?? 'var(--dt-
|
|
1156
|
+
? 'var(--dt-accent, #1d4fd7)'
|
|
1157
|
+
: (movingEvent?.color ?? 'var(--dt-event, var(--dt-accent))')}
|
|
1130
1158
|
aria-hidden="true"
|
|
1131
1159
|
>
|
|
1132
1160
|
{#if ghost.showTime}
|
|
@@ -1169,7 +1197,7 @@ function onWindowKeydown(e) {
|
|
|
1169
1197
|
overflow: hidden;
|
|
1170
1198
|
user-select: none;
|
|
1171
1199
|
font-variant-numeric: tabular-nums;
|
|
1172
|
-
background: var(--dt-paper, none), var(--dt-bg, #
|
|
1200
|
+
background: var(--dt-paper, none), var(--dt-bg, #efebe9);
|
|
1173
1201
|
-webkit-tap-highlight-color: transparent;
|
|
1174
1202
|
}
|
|
1175
1203
|
.tw--auto { overflow: visible; }
|
|
@@ -1186,12 +1214,12 @@ function onWindowKeydown(e) {
|
|
|
1186
1214
|
overscroll-behavior-x: contain;
|
|
1187
1215
|
overscroll-behavior-y: auto;
|
|
1188
1216
|
scrollbar-width: thin;
|
|
1189
|
-
scrollbar-color: var(--dt-scrollbar, rgba(
|
|
1217
|
+
scrollbar-color: var(--dt-scrollbar, rgba(15, 15, 15, 0.1)) transparent;
|
|
1190
1218
|
}
|
|
1191
1219
|
.tw--auto .tw-scroll { overflow-y: visible; }
|
|
1192
1220
|
.tw-scroll::-webkit-scrollbar { width: 5px; height: 5px; }
|
|
1193
1221
|
.tw-scroll::-webkit-scrollbar-thumb {
|
|
1194
|
-
background: var(--dt-scrollbar, rgba(
|
|
1222
|
+
background: var(--dt-scrollbar, rgba(15, 15, 15, 0.1));
|
|
1195
1223
|
border-radius: 4px;
|
|
1196
1224
|
}
|
|
1197
1225
|
.tw-scroll::-webkit-scrollbar-track { background: transparent; }
|
|
@@ -1207,8 +1235,8 @@ function onWindowKeydown(e) {
|
|
|
1207
1235
|
position: sticky;
|
|
1208
1236
|
top: 0;
|
|
1209
1237
|
z-index: 30;
|
|
1210
|
-
background: var(--dt-paper, none), var(--dt-bg, #
|
|
1211
|
-
border-bottom: 1px solid var(--dt-border, rgba(
|
|
1238
|
+
background: var(--dt-paper, none), var(--dt-bg, #efebe9);
|
|
1239
|
+
border-bottom: 1px solid var(--dt-border, rgba(15, 15, 15, 0.08));
|
|
1212
1240
|
}
|
|
1213
1241
|
|
|
1214
1242
|
/* ─── Day header row ─────────────────────────────── */
|
|
@@ -1221,7 +1249,7 @@ function onWindowKeydown(e) {
|
|
|
1221
1249
|
position: sticky;
|
|
1222
1250
|
left: 0;
|
|
1223
1251
|
z-index: 2;
|
|
1224
|
-
background: var(--dt-paper, none), var(--dt-bg, #
|
|
1252
|
+
background: var(--dt-paper, none), var(--dt-bg, #efebe9);
|
|
1225
1253
|
}
|
|
1226
1254
|
|
|
1227
1255
|
.tw-hd {
|
|
@@ -1232,17 +1260,17 @@ function onWindowKeydown(e) {
|
|
|
1232
1260
|
align-items: center;
|
|
1233
1261
|
gap: 4px;
|
|
1234
1262
|
padding: 14px 4px 12px;
|
|
1235
|
-
border-left: 1px solid var(--dt-border, rgba(
|
|
1263
|
+
border-left: 1px solid var(--dt-border, rgba(15, 15, 15, 0.08));
|
|
1236
1264
|
}
|
|
1237
1265
|
|
|
1238
1266
|
.tw-hd-wd {
|
|
1239
1267
|
font: 500 12px/1 var(--dt-sans, system-ui, sans-serif);
|
|
1240
1268
|
letter-spacing: 0.08em;
|
|
1241
1269
|
text-transform: uppercase;
|
|
1242
|
-
color: var(--dt-text-2, rgba(
|
|
1270
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
1243
1271
|
}
|
|
1244
1272
|
.tw-hd--today .tw-hd-wd {
|
|
1245
|
-
color: var(--dt-accent, #
|
|
1273
|
+
color: var(--dt-accent, #1d4fd7);
|
|
1246
1274
|
}
|
|
1247
1275
|
|
|
1248
1276
|
/* The day number is the typography of the grid: large, regular weight. */
|
|
@@ -1253,11 +1281,11 @@ function onWindowKeydown(e) {
|
|
|
1253
1281
|
font: 400 40px/1 var(--dt-sans, system-ui, sans-serif);
|
|
1254
1282
|
font-stretch: 90%;
|
|
1255
1283
|
letter-spacing: -0.02em;
|
|
1256
|
-
color: var(--dt-text, rgba(
|
|
1284
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
1257
1285
|
}
|
|
1258
1286
|
/* Today: the numeral in the accent, nothing else. */
|
|
1259
1287
|
.tw-hd-num--today {
|
|
1260
|
-
color: var(--dt-accent, #
|
|
1288
|
+
color: var(--dt-accent, #1d4fd7);
|
|
1261
1289
|
}
|
|
1262
1290
|
|
|
1263
1291
|
.tw-hd-custom {
|
|
@@ -1268,7 +1296,7 @@ function onWindowKeydown(e) {
|
|
|
1268
1296
|
/* ─── All-day strip ──────────────────────────────── */
|
|
1269
1297
|
.tw-allday {
|
|
1270
1298
|
display: flex;
|
|
1271
|
-
border-top: 1px solid var(--dt-border, rgba(
|
|
1299
|
+
border-top: 1px solid var(--dt-border, rgba(15, 15, 15, 0.08));
|
|
1272
1300
|
}
|
|
1273
1301
|
|
|
1274
1302
|
.tw-ad-gutter {
|
|
@@ -1279,7 +1307,7 @@ function onWindowKeydown(e) {
|
|
|
1279
1307
|
position: sticky;
|
|
1280
1308
|
left: 0;
|
|
1281
1309
|
z-index: 2;
|
|
1282
|
-
background: var(--dt-paper, none), var(--dt-bg, #
|
|
1310
|
+
background: var(--dt-paper, none), var(--dt-bg, #efebe9);
|
|
1283
1311
|
display: flex;
|
|
1284
1312
|
align-items: flex-start;
|
|
1285
1313
|
justify-content: flex-end;
|
|
@@ -1288,7 +1316,7 @@ function onWindowKeydown(e) {
|
|
|
1288
1316
|
.tw-ad-gutter-lb {
|
|
1289
1317
|
font: 500 12px/1.2 var(--dt-sans, system-ui, sans-serif);
|
|
1290
1318
|
letter-spacing: 0.08em;
|
|
1291
|
-
color: var(--dt-text-2, rgba(
|
|
1319
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.66));
|
|
1292
1320
|
text-align: right;
|
|
1293
1321
|
}
|
|
1294
1322
|
|
|
@@ -1299,9 +1327,9 @@ function onWindowKeydown(e) {
|
|
|
1299
1327
|
flex-direction: column;
|
|
1300
1328
|
gap: 2px;
|
|
1301
1329
|
padding: 4px 0 5px;
|
|
1302
|
-
border-left: 1px solid var(--dt-border, rgba(
|
|
1330
|
+
border-left: 1px solid var(--dt-border, rgba(15, 15, 15, 0.08));
|
|
1303
1331
|
}
|
|
1304
|
-
.tw-ad-cell--today { background: var(--dt-today-bg, rgba(
|
|
1332
|
+
.tw-ad-cell--today { background: var(--dt-today-bg, rgba(29, 79, 215, 0.04)); }
|
|
1305
1333
|
|
|
1306
1334
|
.tw-ad {
|
|
1307
1335
|
appearance: none;
|
|
@@ -1337,11 +1365,11 @@ function onWindowKeydown(e) {
|
|
|
1337
1365
|
text-decoration: line-through;
|
|
1338
1366
|
}
|
|
1339
1367
|
.tw-ad--cancelled {
|
|
1340
|
-
background: color-mix(in srgb, var(--ev-color) 55%, var(--dt-bg, #
|
|
1368
|
+
background: color-mix(in srgb, var(--ev-color) 55%, var(--dt-bg, #efebe9));
|
|
1341
1369
|
}
|
|
1342
1370
|
.tw-ad:focus-visible {
|
|
1343
1371
|
outline: none;
|
|
1344
|
-
box-shadow: inset 0 0 0 2px var(--dt-btn-text, #fff), 0 0 0 2px var(--dt-accent, #
|
|
1372
|
+
box-shadow: inset 0 0 0 2px var(--dt-btn-text, #fff), 0 0 0 2px var(--dt-accent, #1d4fd7);
|
|
1345
1373
|
}
|
|
1346
1374
|
|
|
1347
1375
|
.tw-ad-title {
|
|
@@ -1384,19 +1412,19 @@ function onWindowKeydown(e) {
|
|
|
1384
1412
|
appearance: none;
|
|
1385
1413
|
background: none;
|
|
1386
1414
|
border: none;
|
|
1387
|
-
border-radius:
|
|
1415
|
+
border-radius: 0;
|
|
1388
1416
|
text-align: left;
|
|
1389
1417
|
align-self: flex-start;
|
|
1390
1418
|
font: 400 12.5px/1 var(--dt-sans, system-ui, sans-serif);
|
|
1391
|
-
color: var(--dt-text-2, rgba(
|
|
1419
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
1392
1420
|
padding: 2px 6px;
|
|
1393
1421
|
cursor: pointer;
|
|
1394
1422
|
-webkit-tap-highlight-color: transparent;
|
|
1395
1423
|
}
|
|
1396
|
-
.tw-ad-more:hover { color: var(--dt-text, rgba(
|
|
1424
|
+
.tw-ad-more:hover { color: var(--dt-text, rgba(15, 15, 15, 0.87)); }
|
|
1397
1425
|
.tw-ad-more:focus-visible {
|
|
1398
1426
|
outline: none;
|
|
1399
|
-
box-shadow: 0 0 0 2px var(--dt-
|
|
1427
|
+
box-shadow: 0 0 0 2px var(--dt-text, #0f0f0f);
|
|
1400
1428
|
}
|
|
1401
1429
|
|
|
1402
1430
|
/* ─── Grid body ──────────────────────────────────── */
|
|
@@ -1411,8 +1439,8 @@ function onWindowKeydown(e) {
|
|
|
1411
1439
|
position: sticky;
|
|
1412
1440
|
left: 0;
|
|
1413
1441
|
z-index: 20;
|
|
1414
|
-
background: var(--dt-paper, none), var(--dt-bg, #
|
|
1415
|
-
border-right: 1px solid var(--dt-border, rgba(
|
|
1442
|
+
background: var(--dt-paper, none), var(--dt-bg, #efebe9);
|
|
1443
|
+
border-right: 1px solid var(--dt-border, rgba(15, 15, 15, 0.08));
|
|
1416
1444
|
}
|
|
1417
1445
|
|
|
1418
1446
|
/* Timetable hour: the numeral carries the rank, the suffix sits raised
|
|
@@ -1429,7 +1457,7 @@ function onWindowKeydown(e) {
|
|
|
1429
1457
|
font-stretch: 85%;
|
|
1430
1458
|
font-variant-numeric: tabular-nums;
|
|
1431
1459
|
letter-spacing: -0.02em;
|
|
1432
|
-
color: var(--dt-text, rgba(
|
|
1460
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
1433
1461
|
white-space: nowrap;
|
|
1434
1462
|
}
|
|
1435
1463
|
.tw-gutter-lb::after {
|
|
@@ -1439,7 +1467,7 @@ function onWindowKeydown(e) {
|
|
|
1439
1467
|
height: 1px;
|
|
1440
1468
|
margin-left: 5px;
|
|
1441
1469
|
align-self: center;
|
|
1442
|
-
background: var(--dt-border-day, rgba(
|
|
1470
|
+
background: var(--dt-border-day, rgba(15, 15, 15, 0.3));
|
|
1443
1471
|
}
|
|
1444
1472
|
.tw-gutter-lb--under {
|
|
1445
1473
|
visibility: hidden;
|
|
@@ -1449,7 +1477,7 @@ function onWindowKeydown(e) {
|
|
|
1449
1477
|
font-weight: 500;
|
|
1450
1478
|
line-height: 1;
|
|
1451
1479
|
letter-spacing: 0;
|
|
1452
|
-
color: var(--dt-text-2, rgba(
|
|
1480
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
1453
1481
|
}
|
|
1454
1482
|
|
|
1455
1483
|
/* The clock beside the now line, and the drag's edges while it lasts —
|
|
@@ -1461,16 +1489,16 @@ function onWindowKeydown(e) {
|
|
|
1461
1489
|
transform: translateY(-50%);
|
|
1462
1490
|
padding: 2px 4px;
|
|
1463
1491
|
border-radius: 0;
|
|
1464
|
-
background: var(--dt-surface, var(--dt-bg, #
|
|
1492
|
+
background: var(--dt-surface, var(--dt-bg, #efebe9));
|
|
1465
1493
|
font: 500 11px/1.2 var(--dt-sans, system-ui, sans-serif);
|
|
1466
1494
|
font-variant-numeric: tabular-nums;
|
|
1467
|
-
color: var(--dt-accent, #
|
|
1495
|
+
color: var(--dt-accent, #1d4fd7);
|
|
1468
1496
|
white-space: nowrap;
|
|
1469
1497
|
z-index: 2;
|
|
1470
1498
|
}
|
|
1471
1499
|
/* The clock is a reversed plate on the accent, like a board's live time. */
|
|
1472
1500
|
.tw-gutter-now {
|
|
1473
|
-
background: var(--dt-accent, #
|
|
1501
|
+
background: var(--dt-accent, #1d4fd7);
|
|
1474
1502
|
color: var(--dt-btn-text, #ffffff);
|
|
1475
1503
|
}
|
|
1476
1504
|
|
|
@@ -1495,7 +1523,7 @@ function onWindowKeydown(e) {
|
|
|
1495
1523
|
left: 0;
|
|
1496
1524
|
right: 0;
|
|
1497
1525
|
height: 1px;
|
|
1498
|
-
background: var(--dt-border, rgba(
|
|
1526
|
+
background: var(--dt-border, rgba(15, 15, 15, 0.08));
|
|
1499
1527
|
}
|
|
1500
1528
|
.tw-line--half { opacity: 0.4; }
|
|
1501
1529
|
.tw-now-week {
|
|
@@ -1503,7 +1531,7 @@ function onWindowKeydown(e) {
|
|
|
1503
1531
|
left: 0;
|
|
1504
1532
|
right: 0;
|
|
1505
1533
|
height: 0;
|
|
1506
|
-
border-top: 2px solid var(--dt-accent, #
|
|
1534
|
+
border-top: 2px solid var(--dt-accent, #1d4fd7);
|
|
1507
1535
|
opacity: 0.85;
|
|
1508
1536
|
transform: translateY(-1px);
|
|
1509
1537
|
}
|
|
@@ -1513,11 +1541,11 @@ function onWindowKeydown(e) {
|
|
|
1513
1541
|
flex: 1 1 0;
|
|
1514
1542
|
min-width: var(--tw-col-min, 110px);
|
|
1515
1543
|
position: relative;
|
|
1516
|
-
border-left: 1px solid var(--dt-border, rgba(
|
|
1544
|
+
border-left: 1px solid var(--dt-border, rgba(15, 15, 15, 0.08));
|
|
1517
1545
|
box-sizing: border-box;
|
|
1518
1546
|
}
|
|
1519
1547
|
.tw-col:focus-visible {
|
|
1520
|
-
outline: 2px solid var(--dt-
|
|
1548
|
+
outline: 2px solid var(--dt-text, #0f0f0f);
|
|
1521
1549
|
outline-offset: -2px;
|
|
1522
1550
|
}
|
|
1523
1551
|
/* The gutter's right border already bounds the first column */
|
|
@@ -1526,25 +1554,25 @@ function onWindowKeydown(e) {
|
|
|
1526
1554
|
/* --tw-col-wash: the column's ground, repeated under an event that the
|
|
1527
1555
|
now line crosses (that event is opaque, so the line runs beneath it). */
|
|
1528
1556
|
.tw-col { background: var(--tw-col-wash, transparent); }
|
|
1529
|
-
.tw-col--today { --tw-col-wash: var(--dt-today-bg, rgba(
|
|
1557
|
+
.tw-col--today { --tw-col-wash: var(--dt-today-bg, rgba(29, 79, 215, 0.04)); }
|
|
1530
1558
|
/* Dim past days with a wash, never a subtree opacity (event contrast) */
|
|
1531
1559
|
.tw-col--past {
|
|
1532
|
-
--tw-col-wash: color-mix(in srgb, var(--dt-text, rgba(
|
|
1560
|
+
--tw-col-wash: color-mix(in srgb, var(--dt-text, rgba(15, 15, 15, 0.87)) 4%, transparent);
|
|
1533
1561
|
}
|
|
1534
1562
|
/* What has already happened steps back; a cancelled block keeps its own look. */
|
|
1535
1563
|
.tw-ev--past:not(.tw-ev--cancelled) {
|
|
1536
1564
|
opacity: 0.78;
|
|
1537
1565
|
}
|
|
1538
1566
|
.tw-col--weekend:not(.tw-col--today):not(.tw-col--past) {
|
|
1539
|
-
--tw-col-wash: var(--dt-weekend-bg, rgba(
|
|
1567
|
+
--tw-col-wash: var(--dt-weekend-bg, rgba(15, 15, 15, 0.012));
|
|
1540
1568
|
}
|
|
1541
1569
|
.tw-col--disabled {
|
|
1542
1570
|
background: repeating-linear-gradient(
|
|
1543
1571
|
45deg,
|
|
1544
1572
|
transparent,
|
|
1545
1573
|
transparent 6px,
|
|
1546
|
-
var(--dt-border, rgba(
|
|
1547
|
-
var(--dt-border, rgba(
|
|
1574
|
+
var(--dt-border, rgba(15, 15, 15, 0.08)) 6px,
|
|
1575
|
+
var(--dt-border, rgba(15, 15, 15, 0.08)) 7px
|
|
1548
1576
|
) !important;
|
|
1549
1577
|
}
|
|
1550
1578
|
|
|
@@ -1556,8 +1584,8 @@ function onWindowKeydown(e) {
|
|
|
1556
1584
|
z-index: 2;
|
|
1557
1585
|
background: repeating-linear-gradient(
|
|
1558
1586
|
-45deg,
|
|
1559
|
-
color-mix(in srgb, var(--dt-text, rgba(
|
|
1560
|
-
color-mix(in srgb, var(--dt-text, rgba(
|
|
1587
|
+
color-mix(in srgb, var(--dt-text, rgba(15, 15, 15, 0.87)) 4%, transparent),
|
|
1588
|
+
color-mix(in srgb, var(--dt-text, rgba(15, 15, 15, 0.87)) 4%, transparent) 4px,
|
|
1561
1589
|
transparent 4px,
|
|
1562
1590
|
transparent 8px
|
|
1563
1591
|
);
|
|
@@ -1569,7 +1597,7 @@ function onWindowKeydown(e) {
|
|
|
1569
1597
|
}
|
|
1570
1598
|
.tw-blocked-lb {
|
|
1571
1599
|
font: 500 11px/1 var(--dt-sans, system-ui, sans-serif);
|
|
1572
|
-
color: var(--dt-text-2, rgba(
|
|
1600
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
1573
1601
|
text-transform: uppercase;
|
|
1574
1602
|
letter-spacing: 0.04em;
|
|
1575
1603
|
white-space: nowrap;
|
|
@@ -1584,7 +1612,7 @@ function onWindowKeydown(e) {
|
|
|
1584
1612
|
left: 0;
|
|
1585
1613
|
right: 0;
|
|
1586
1614
|
height: 0;
|
|
1587
|
-
border-top: 2px solid var(--dt-accent, #
|
|
1615
|
+
border-top: 2px solid var(--dt-accent, #1d4fd7);
|
|
1588
1616
|
z-index: 5;
|
|
1589
1617
|
pointer-events: none;
|
|
1590
1618
|
transform: translateY(-1px);
|
|
@@ -1596,7 +1624,7 @@ function onWindowKeydown(e) {
|
|
|
1596
1624
|
height: 8px;
|
|
1597
1625
|
margin-top: -4px;
|
|
1598
1626
|
border-radius: 50%;
|
|
1599
|
-
background: var(--dt-accent, #
|
|
1627
|
+
background: var(--dt-accent, #1d4fd7);
|
|
1600
1628
|
z-index: 12;
|
|
1601
1629
|
pointer-events: none;
|
|
1602
1630
|
}
|
|
@@ -1619,7 +1647,7 @@ function onWindowKeydown(e) {
|
|
|
1619
1647
|
-webkit-tap-highlight-color: transparent;
|
|
1620
1648
|
}
|
|
1621
1649
|
.tw-ev:hover {
|
|
1622
|
-
background: var(--dt-hover, rgba(
|
|
1650
|
+
background: var(--dt-hover, rgba(15, 15, 15, 0.04));
|
|
1623
1651
|
z-index: 8;
|
|
1624
1652
|
}
|
|
1625
1653
|
/* Short blocks keep duration-proportional height, but get a 44px
|
|
@@ -1639,7 +1667,7 @@ function onWindowKeydown(e) {
|
|
|
1639
1667
|
z-index: 9;
|
|
1640
1668
|
}
|
|
1641
1669
|
.tw-ev--current {
|
|
1642
|
-
background: var(--dt-accent-dim, rgba(
|
|
1670
|
+
background: var(--dt-accent-dim, rgba(29, 79, 215, 0.12));
|
|
1643
1671
|
}
|
|
1644
1672
|
/* An event the now line crosses lays its column's ground (and its own
|
|
1645
1673
|
wash) over the paper, so the line passes beneath its text. */
|
|
@@ -1648,10 +1676,10 @@ function onWindowKeydown(e) {
|
|
|
1648
1676
|
linear-gradient(var(--tw-ev-wash, transparent), var(--tw-ev-wash, transparent)),
|
|
1649
1677
|
linear-gradient(var(--tw-col-wash, transparent), var(--tw-col-wash, transparent)),
|
|
1650
1678
|
var(--dt-paper, none),
|
|
1651
|
-
var(--dt-bg, #
|
|
1679
|
+
var(--dt-bg, #efebe9);
|
|
1652
1680
|
}
|
|
1653
|
-
.tw-ev--on-now.tw-ev--current { --tw-ev-wash: var(--dt-accent-dim, rgba(
|
|
1654
|
-
.tw-ev--on-now:hover { --tw-ev-wash: var(--dt-hover, rgba(
|
|
1681
|
+
.tw-ev--on-now.tw-ev--current { --tw-ev-wash: var(--dt-accent-dim, rgba(29, 79, 215, 0.12)); }
|
|
1682
|
+
.tw-ev--on-now:hover { --tw-ev-wash: var(--dt-hover, rgba(15, 15, 15, 0.04)); }
|
|
1655
1683
|
.tw-ev--resizing {
|
|
1656
1684
|
z-index: 50;
|
|
1657
1685
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.25);
|
|
@@ -1669,12 +1697,12 @@ function onWindowKeydown(e) {
|
|
|
1669
1697
|
grid; a tentative one is set in grey with a dashed bar. */
|
|
1670
1698
|
.tw-ev--cancelled .tw-ev-title {
|
|
1671
1699
|
text-decoration: line-through;
|
|
1672
|
-
color: var(--dt-text-2, rgba(
|
|
1700
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
1673
1701
|
}
|
|
1674
1702
|
.tw-ev--cancelled .tw-ev-stripe { opacity: 0.45; /* decorative bar only */ }
|
|
1675
1703
|
.tw-ev--tentative .tw-ev-title,
|
|
1676
1704
|
.tw-ev--full .tw-ev-title {
|
|
1677
|
-
color: var(--dt-text-2, rgba(
|
|
1705
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
1678
1706
|
}
|
|
1679
1707
|
.tw-ev--tentative .tw-ev-stripe,
|
|
1680
1708
|
.tw-ev--limited .tw-ev-stripe {
|
|
@@ -1723,7 +1751,7 @@ function onWindowKeydown(e) {
|
|
|
1723
1751
|
order: 1;
|
|
1724
1752
|
font: 400 14px/1.2 var(--dt-sans, system-ui, sans-serif);
|
|
1725
1753
|
font-variant-numeric: tabular-nums;
|
|
1726
|
-
color: var(--dt-text, rgba(
|
|
1754
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
1727
1755
|
white-space: nowrap;
|
|
1728
1756
|
flex-shrink: 0;
|
|
1729
1757
|
}
|
|
@@ -1735,7 +1763,7 @@ function onWindowKeydown(e) {
|
|
|
1735
1763
|
.tw-ev-title {
|
|
1736
1764
|
order: 0;
|
|
1737
1765
|
font: 500 15px/1.25 var(--dt-sans, system-ui, sans-serif);
|
|
1738
|
-
color: var(--dt-text, rgba(
|
|
1766
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
1739
1767
|
white-space: nowrap;
|
|
1740
1768
|
overflow: hidden;
|
|
1741
1769
|
text-overflow: ellipsis;
|
|
@@ -1744,7 +1772,7 @@ function onWindowKeydown(e) {
|
|
|
1744
1772
|
.tw-ev-loc {
|
|
1745
1773
|
order: 2;
|
|
1746
1774
|
font: 400 12.5px/1.2 var(--dt-sans, system-ui, sans-serif);
|
|
1747
|
-
color: var(--dt-text, rgba(
|
|
1775
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
1748
1776
|
white-space: nowrap;
|
|
1749
1777
|
overflow: hidden;
|
|
1750
1778
|
text-overflow: ellipsis;
|
|
@@ -1829,7 +1857,7 @@ function onWindowKeydown(e) {
|
|
|
1829
1857
|
right: 3px;
|
|
1830
1858
|
z-index: 40;
|
|
1831
1859
|
border-radius: 0;
|
|
1832
|
-
background: color-mix(in srgb, var(--ev-color) 12%, var(--dt-surface, var(--dt-bg, #
|
|
1860
|
+
background: color-mix(in srgb, var(--ev-color) 12%, var(--dt-surface, var(--dt-bg, #efebe9)));
|
|
1833
1861
|
outline: 1px solid color-mix(in srgb, var(--ev-color) 45%, transparent);
|
|
1834
1862
|
box-shadow: 0 6px 18px color-mix(in srgb, var(--ev-color) 24%, rgba(0, 0, 0, 0.22));
|
|
1835
1863
|
display: flex;
|
|
@@ -1849,12 +1877,12 @@ function onWindowKeydown(e) {
|
|
|
1849
1877
|
.tw-ghost-time {
|
|
1850
1878
|
font: 500 12.5px/1.15 var(--dt-sans, system-ui, sans-serif);
|
|
1851
1879
|
font-variant-numeric: tabular-nums;
|
|
1852
|
-
color: var(--ev-color, var(--dt-accent, #
|
|
1880
|
+
color: var(--ev-color, var(--dt-accent, #1d4fd7));
|
|
1853
1881
|
white-space: nowrap;
|
|
1854
1882
|
}
|
|
1855
1883
|
.tw-ghost-title {
|
|
1856
1884
|
font: 500 12.5px/1.2 var(--dt-sans, system-ui, sans-serif);
|
|
1857
|
-
color: var(--dt-text, rgba(
|
|
1885
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
1858
1886
|
white-space: nowrap;
|
|
1859
1887
|
overflow: hidden;
|
|
1860
1888
|
text-overflow: ellipsis;
|
|
@@ -1876,7 +1904,7 @@ function onWindowKeydown(e) {
|
|
|
1876
1904
|
overflow: hidden scroll container. */
|
|
1877
1905
|
.tw-ev:focus-visible {
|
|
1878
1906
|
outline: none;
|
|
1879
|
-
box-shadow: 0 0 0 2px var(--dt-accent, #
|
|
1907
|
+
box-shadow: 0 0 0 2px var(--dt-accent, #1d4fd7);
|
|
1880
1908
|
z-index: 9;
|
|
1881
1909
|
}
|
|
1882
1910
|
|
|
@@ -48,6 +48,8 @@ export interface CalendarContext {
|
|
|
48
48
|
readonly emptySnippet: Snippet | undefined;
|
|
49
49
|
/** Per-instance labels (Calendar's `labels` prop merged over globals); global labels when headless. */
|
|
50
50
|
readonly labels: CalendarLabels;
|
|
51
|
+
/** Say something through the calendar's polite status line (no-op when headless). */
|
|
52
|
+
announce(text: string): void;
|
|
51
53
|
}
|
|
52
54
|
/**
|
|
53
55
|
* Read the calendar context.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nomideusz/svelte-calendar",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "A themeable Svelte 5 calendar: day, week, scrolling-week and month views, agenda lists, touch-first mobile layouts, drag-and-drop, timezones, a headless API and an embeddable web component.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": [
|