@nomideusz/svelte-calendar 1.2.0 → 1.4.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.
@@ -64,6 +64,7 @@ const MAX_EVENTS_SHOWN = 5;
64
64
  // mount re-centres once the events have landed.
65
65
  const CHIP_H = 22;
66
66
  const CHIP_GAP = 3;
67
+ const NOW_H = 18;
67
68
  /** The day's hours at their floor height — a quiet week is short, a busy
68
69
  * day grows its row. Chips sit on this axis by start time. */
69
70
  const TIME_H = 120;
@@ -122,26 +123,31 @@ function timeTop(hoursIntoDay) {
122
123
  return Math.min(Math.max(f, 0), 1) * (TIME_H - CHIP_H);
123
124
  }
124
125
  /** Each chip at its start time, or just under the chip before it when that
125
- * one is in the way: the order is time, the height is time, nothing overlaps. */
126
- function chipTops(list, dayMs) {
126
+ * one is in the way: the order is time, the height is time, nothing overlaps.
127
+ * On today the now line is one more item on the axis: at the clock's
128
+ * height, under every chip that has started (pushed-down chips would read
129
+ * as still to come), and it pushes the chips to come down by its plate,
130
+ * so the plate never covers a chip's text. `end` is where the last item ends. */
131
+ function chipTops(list, dayMs, withNow = false) {
127
132
  const tops = [];
128
133
  let min = 0;
134
+ let nowY = null;
135
+ const placeNow = () => {
136
+ nowY = Math.max(timeTop(hourOf(clock.tick, dayMs)), min - CHIP_GAP + NOW_H / 2);
137
+ min = nowY + NOW_H / 2 + CHIP_GAP;
138
+ };
129
139
  for (const ev of list) {
140
+ if (withNow && nowY === null && ev.start.getTime() > clock.tick) placeNow();
130
141
  const top = Math.max(timeTop(hourOf(ev.start.getTime(), dayMs)), min);
131
142
  tops.push(top);
132
143
  min = top + CHIP_H + CHIP_GAP;
133
144
  }
134
- return tops;
135
- }
136
- /** The now-line: at the clock's height (pinned to the axis ends outside
137
- * it), but never above a chip that has already started — pushed-down
138
- * chips would read as still to come. */
139
- function nowTop(list, tops, dayMs) {
140
- let y = timeTop(hourOf(clock.tick, dayMs));
141
- list.forEach((ev, i) => {
142
- if (ev.start.getTime() <= clock.tick) y = Math.max(y, tops[i] + CHIP_H + CHIP_GAP / 2);
143
- });
144
- return y;
145
+ if (withNow && nowY === null) placeNow();
146
+ return {
147
+ tops,
148
+ nowY,
149
+ end: Math.max(0, min - CHIP_GAP)
150
+ };
145
151
  }
146
152
  const _initMs = untrack(() => sod(focusDate?.getTime() ?? Date.now()));
147
153
  let internalFocusMs = $state(_initMs);
@@ -836,8 +842,9 @@ function onCellKeydown(e, ms) {
836
842
  {@const previewTimedEvent = dragPreviewTimedForDay(day.ms)}
837
843
  {@const previewSegment = dragPreviewSegmentForDay(day.ms)}
838
844
  {@const shownTimed = visibleTimedEvents.slice(0, isExpanded ? visibleTimedEvents.length : timedCap)}
839
- {@const tops = chipTops(shownTimed, day.ms)}
840
- {@const nowY = day.isToday ? nowTop(shownTimed, tops, day.ms) : null}
845
+ {@const axis = chipTops(shownTimed, day.ms, day.isToday)}
846
+ {@const tops = axis.tops}
847
+ {@const nowY = axis.nowY}
841
848
  {@const inset = day.monthLabel ? MONTH_INSET : 0}
842
849
  <div
843
850
  class="wg-cell"
@@ -919,7 +926,7 @@ function onCellKeydown(e, ms) {
919
926
  class:wg-ev--tentative={ev.status === 'tentative'}
920
927
  class:wg-ev--full={ev.status === 'full'}
921
928
  class:wg-ev--limited={ev.status === 'limited'}
922
- style:--ev-color={ev.color ?? 'var(--dt-accent)'}
929
+ style:--ev-color={ev.color ?? 'var(--dt-event, var(--dt-accent))'}
923
930
  style:margin-top="{tops[i] - (i ? tops[i - 1] + CHIP_H : 0)}px"
924
931
  role="button"
925
932
  tabindex="0"
@@ -935,6 +942,7 @@ function onCellKeydown(e, ms) {
935
942
  <button
936
943
  type="button"
937
944
  class="wg-ev-more"
945
+ style:margin-top="{axis.end - (tops.length ? tops[tops.length - 1] + CHIP_H : 0) + 2}px"
938
946
  aria-expanded={isExpanded}
939
947
  onclick={(e) => { e.stopPropagation(); expandedCells[day.ms] = !isExpanded; }}
940
948
  >{isExpanded ? L.showLess : L.nMore(hiddenCount)}</button>
@@ -943,7 +951,7 @@ function onCellKeydown(e, ms) {
943
951
  <!-- The ghost floats at its own time; it pushes nothing aside -->
944
952
  <div
945
953
  class="wg-ev wg-ev--drag-preview"
946
- style:--ev-color={previewTimedEvent.color ?? 'var(--dt-accent)'}
954
+ style:--ev-color={previewTimedEvent.color ?? 'var(--dt-event, var(--dt-accent))'}
947
955
  style:top="{timeTop(hourOf(previewTimedEvent.start.getTime(), day.ms))}px"
948
956
  aria-hidden="true"
949
957
  in:previewReceive={{ key: previewKeySnapshot.get('timed') ?? '' }}
@@ -1038,13 +1046,13 @@ function onCellKeydown(e, ms) {
1038
1046
  overflow-x: auto;
1039
1047
  box-sizing: border-box;
1040
1048
  scrollbar-width: thin;
1041
- scrollbar-color: var(--dt-scrollbar, rgba(0, 0, 0, 0.1)) transparent;
1049
+ scrollbar-color: var(--dt-scrollbar, rgba(15, 15, 15, 0.1)) transparent;
1042
1050
  }
1043
1051
  .wg--auto .wg-body { overflow-y: visible; }
1044
1052
 
1045
1053
  .wg-body::-webkit-scrollbar { width: 4px; }
1046
1054
  .wg-body::-webkit-scrollbar-thumb {
1047
- background: var(--dt-scrollbar, rgba(0, 0, 0, 0.1));
1055
+ background: var(--dt-scrollbar, rgba(15, 15, 15, 0.1));
1048
1056
  border-radius: 0;
1049
1057
  }
1050
1058
  .wg-body::-webkit-scrollbar-track { background: transparent; }
@@ -1062,14 +1070,14 @@ function onCellKeydown(e, ms) {
1062
1070
  display: flex;
1063
1071
  border-radius: 0;
1064
1072
  margin: var(--wg-row-margin, 12px) 8px;
1065
- border: 1px solid var(--dt-border, rgba(0, 0, 0, 0.08));
1073
+ border: 1px solid var(--dt-border, rgba(15, 15, 15, 0.08));
1066
1074
  overflow: hidden;
1067
1075
  }
1068
1076
 
1069
1077
  .wg-week--current {
1070
- background: var(--dt-today-bg, rgba(37, 99, 235, 0.04));
1078
+ background: var(--dt-today-bg, rgba(29, 79, 215, 0.04));
1071
1079
  /* The current row's frame is a day rule, not the accent */
1072
- border-color: var(--dt-border-day, rgba(0, 0, 0, 0.3));
1080
+ border-color: var(--dt-border-day, rgba(15, 15, 15, 0.3));
1073
1081
  }
1074
1082
 
1075
1083
  /* ─── Week body ──────────────────────────────────── */
@@ -1094,7 +1102,7 @@ function onCellKeydown(e, ms) {
1094
1102
  min-width: 90px;
1095
1103
  box-sizing: border-box;
1096
1104
  padding: 4px 4px 8px;
1097
- border-right: 1px solid var(--dt-border, rgba(0, 0, 0, 0.08));
1105
+ border-right: 1px solid var(--dt-border, rgba(15, 15, 15, 0.08));
1098
1106
  cursor: pointer;
1099
1107
  transition: background 0.15s;
1100
1108
  }
@@ -1112,15 +1120,15 @@ function onCellKeydown(e, ms) {
1112
1120
  transform: rotate(180deg);
1113
1121
  text-align: end; /* the rotation puts the end at the top */
1114
1122
  padding: 6px 0;
1115
- font: 700 11px / 22px var(--dt-sans, system-ui, sans-serif);
1123
+ font: 500 12px / 22px var(--dt-sans, system-ui, sans-serif);
1116
1124
  letter-spacing: 0.08em;
1117
1125
  white-space: nowrap;
1118
1126
  overflow: hidden;
1119
- color: var(--dt-text-3, rgba(0, 0, 0, 0.38));
1127
+ color: var(--dt-text-3, rgba(15, 15, 15, 0.38));
1120
1128
  }
1121
1129
  .wg-week--current .wg-month,
1122
1130
  .wg-month--start {
1123
- color: var(--dt-text, rgba(0, 0, 0, 0.87));
1131
+ color: var(--dt-text, rgba(15, 15, 15, 0.87));
1124
1132
  }
1125
1133
  .wg-month--inset {
1126
1134
  position: absolute;
@@ -1128,19 +1136,19 @@ function onCellKeydown(e, ms) {
1128
1136
  left: 2px;
1129
1137
  pointer-events: none;
1130
1138
  }
1131
- .wg-cell:hover { background: var(--dt-hover, rgba(0, 0, 0, 0.015)); }
1139
+ .wg-cell:hover { background: var(--dt-hover, rgba(15, 15, 15, 0.015)); }
1132
1140
 
1133
- .wg-cell--today { background: var(--dt-today-bg, rgba(37, 99, 235, 0.04)); }
1141
+ .wg-cell--today { background: var(--dt-today-bg, rgba(29, 79, 215, 0.04)); }
1134
1142
  .wg-cell--drop {
1135
- background: var(--dt-accent-dim, rgba(37, 99, 235, 0.12)) !important;
1136
- box-shadow: inset 0 0 0 2px var(--dt-accent, #2563eb);
1143
+ background: var(--dt-accent-dim, rgba(29, 79, 215, 0.12)) !important;
1144
+ box-shadow: inset 0 0 0 2px var(--dt-accent, #1d4fd7);
1137
1145
  }
1138
- .wg-cell--today:hover { background: var(--dt-hover, rgba(0, 0, 0, 0.04)); }
1146
+ .wg-cell--today:hover { background: var(--dt-hover, rgba(15, 15, 15, 0.04)); }
1139
1147
 
1140
1148
  /* Non-current weeks sit on the same paper; only the header ink softens,
1141
1149
  and past events print a shade lighter. */
1142
1150
  .wg-week:not(.wg-week--current) .wg-day-num {
1143
- color: var(--dt-text-2, rgba(0, 0, 0, 0.54));
1151
+ color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
1144
1152
  }
1145
1153
  .wg-cell--past .wg-ev:not(.wg-ev--cancelled) {
1146
1154
  opacity: 0.78;
@@ -1148,7 +1156,7 @@ function onCellKeydown(e, ms) {
1148
1156
 
1149
1157
  /* equalDays: when no cells are marked past, all are full brightness */
1150
1158
 
1151
- .wg-cell--weekend { background: var(--dt-weekend-bg, rgba(0, 0, 0, 0.012)); }
1159
+ .wg-cell--weekend { background: var(--dt-weekend-bg, rgba(15, 15, 15, 0.012)); }
1152
1160
 
1153
1161
  /* ─── Disabled cell ──────────────────────────────── */
1154
1162
  .wg-cell--disabled {
@@ -1156,8 +1164,8 @@ function onCellKeydown(e, ms) {
1156
1164
  45deg,
1157
1165
  transparent,
1158
1166
  transparent 6px,
1159
- var(--dt-border, rgba(0, 0, 0, 0.08)) 6px,
1160
- var(--dt-border, rgba(0, 0, 0, 0.08)) 7px
1167
+ var(--dt-border, rgba(15, 15, 15, 0.08)) 6px,
1168
+ var(--dt-border, rgba(15, 15, 15, 0.08)) 7px
1161
1169
  ) !important;
1162
1170
  }
1163
1171
 
@@ -1176,16 +1184,16 @@ function onCellKeydown(e, ms) {
1176
1184
  border-radius: 0;
1177
1185
  background: repeating-linear-gradient(
1178
1186
  -45deg,
1179
- color-mix(in srgb, var(--dt-text, rgba(0, 0, 0, 0.87)) 4%, transparent),
1180
- color-mix(in srgb, var(--dt-text, rgba(0, 0, 0, 0.87)) 4%, transparent) 3px,
1187
+ color-mix(in srgb, var(--dt-text, rgba(15, 15, 15, 0.87)) 4%, transparent),
1188
+ color-mix(in srgb, var(--dt-text, rgba(15, 15, 15, 0.87)) 4%, transparent) 3px,
1181
1189
  transparent 3px,
1182
1190
  transparent 6px
1183
1191
  );
1184
1192
  }
1185
1193
 
1186
1194
  .wg-blocked-label {
1187
- font: 500 10px/1 var(--dt-sans, system-ui, sans-serif);
1188
- color: var(--dt-text-2, rgba(0, 0, 0, 0.54));
1195
+ font: 500 11px/1 var(--dt-sans, system-ui, sans-serif);
1196
+ color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
1189
1197
  text-transform: uppercase;
1190
1198
  letter-spacing: 0.04em;
1191
1199
  white-space: nowrap;
@@ -1208,32 +1216,33 @@ function onCellKeydown(e, ms) {
1208
1216
  }
1209
1217
 
1210
1218
  .wg-day-wd {
1211
- font: 400 11px / 1 var(--dt-sans, system-ui, sans-serif);
1212
- letter-spacing: 0.04em;
1219
+ font: 500 12px / 1 var(--dt-sans, system-ui, sans-serif);
1220
+ letter-spacing: 0.08em;
1213
1221
  text-transform: uppercase;
1214
- color: var(--dt-text-3, rgba(0, 0, 0, 0.38));
1222
+ color: var(--dt-text-3, rgba(15, 15, 15, 0.38));
1215
1223
  }
1216
1224
 
1217
1225
  .wg-week--current .wg-day-wd {
1218
- color: var(--dt-text-2, rgba(0, 0, 0, 0.54));
1226
+ color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
1219
1227
  }
1220
1228
 
1221
1229
  .wg-day-num {
1222
- font: 700 14px / 1 var(--dt-sans, system-ui, sans-serif);
1223
- color: var(--dt-text, rgba(0, 0, 0, 0.87));
1230
+ font: 400 15px / 1 var(--dt-sans, system-ui, sans-serif);
1231
+ font-variant-numeric: tabular-nums;
1232
+ color: var(--dt-text, rgba(15, 15, 15, 0.87));
1224
1233
  }
1225
1234
 
1226
1235
  .wg-week--current .wg-day-num {
1227
- color: var(--dt-text, rgba(0, 0, 0, 0.87));
1236
+ color: var(--dt-text, rgba(15, 15, 15, 0.87));
1228
1237
  }
1229
1238
 
1230
1239
  /* Today's pill — after the week rules above, which it must beat */
1231
1240
  .wg-cell-hd--today .wg-day-wd,
1232
1241
  .wg-cell-hd--today .wg-day-num {
1233
- color: var(--dt-accent, #2563eb);
1242
+ color: var(--dt-accent, #1d4fd7);
1234
1243
  }
1235
1244
  .wg-cell-hd--today .wg-day-num {
1236
- box-shadow: inset 0 -2px 0 var(--dt-accent, #2563eb);
1245
+ box-shadow: inset 0 -2px 0 var(--dt-accent, #1d4fd7);
1237
1246
  padding-bottom: 2px;
1238
1247
  }
1239
1248
 
@@ -1282,11 +1291,11 @@ function onCellKeydown(e, ms) {
1282
1291
 
1283
1292
  .wg-ad:focus-visible {
1284
1293
  outline: none;
1285
- box-shadow: inset 0 0 0 2px var(--dt-btn-text, #fff), 0 0 0 2px var(--dt-accent, #2563eb);
1294
+ box-shadow: inset 0 0 0 2px var(--dt-btn-text, #fff), 0 0 0 2px var(--dt-accent, #1d4fd7);
1286
1295
  }
1287
1296
 
1288
1297
  .wg-ad-title {
1289
- font: 500 11px / 1.1 var(--dt-sans, system-ui, sans-serif);
1298
+ font: 500 13.5px / 1.1 var(--dt-sans, system-ui, sans-serif);
1290
1299
  color: inherit;
1291
1300
  white-space: nowrap;
1292
1301
  overflow: hidden;
@@ -1332,13 +1341,14 @@ function onCellKeydown(e, ms) {
1332
1341
  .wg-now::after {
1333
1342
  content: '';
1334
1343
  flex: 1;
1335
- border-top: 2px solid var(--dt-accent, #2563eb);
1344
+ border-top: 2px solid var(--dt-accent, #1d4fd7);
1336
1345
  }
1337
1346
  .wg-now-time {
1338
- font: 500 10px / 1 var(--dt-sans, system-ui, sans-serif);
1347
+ font: 500 11px / 1.2 var(--dt-sans, system-ui, sans-serif);
1348
+ font-variant-numeric: tabular-nums;
1339
1349
  padding: 2px 4px;
1340
1350
  border-radius: 0;
1341
- background: var(--dt-accent, #2563eb);
1351
+ background: var(--dt-accent, #1d4fd7);
1342
1352
  color: var(--dt-btn-text, #fff);
1343
1353
  }
1344
1354
  /* Where a dragged-in class would land: the now-line's shape, dashed */
@@ -1348,9 +1358,6 @@ function onCellKeydown(e, ms) {
1348
1358
  .wg-drop::after {
1349
1359
  border-top-style: dashed;
1350
1360
  }
1351
- .wg-drop .wg-now-time {
1352
- font-weight: 600;
1353
- }
1354
1361
 
1355
1362
  .wg-ev {
1356
1363
  position: relative; /* above the blocked bands */
@@ -1379,7 +1386,7 @@ function onCellKeydown(e, ms) {
1379
1386
  }
1380
1387
 
1381
1388
  .wg-ev:hover {
1382
- background: var(--dt-hover, rgba(0, 0, 0, 0.04));
1389
+ background: var(--dt-hover, rgba(15, 15, 15, 0.04));
1383
1390
  }
1384
1391
 
1385
1392
  .wg-ev--drag-preview {
@@ -1389,7 +1396,7 @@ function onCellKeydown(e, ms) {
1389
1396
  z-index: 8;
1390
1397
  opacity: 0.95;
1391
1398
  pointer-events: none;
1392
- background: var(--dt-hover, rgba(0, 0, 0, 0.04));
1399
+ background: var(--dt-hover, rgba(15, 15, 15, 0.04));
1393
1400
  box-shadow: inset 0 0 0 1px var(--ev-color);
1394
1401
  cursor: grabbing;
1395
1402
  }
@@ -1399,13 +1406,13 @@ function onCellKeydown(e, ms) {
1399
1406
  }
1400
1407
 
1401
1408
  .wg-ev--current {
1402
- background: var(--dt-accent-dim, rgba(37, 99, 235, 0.12));
1409
+ background: var(--dt-accent-dim, rgba(29, 79, 215, 0.12));
1403
1410
  }
1404
1411
 
1405
1412
  /* Printed states: struck through, grey, or a dashed bar — never a tint */
1406
1413
  .wg-ev--cancelled .wg-ev-title {
1407
1414
  text-decoration: line-through;
1408
- color: var(--dt-text-2, rgba(0, 0, 0, 0.54));
1415
+ color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
1409
1416
  }
1410
1417
  .wg-ev--cancelled::before,
1411
1418
  .wg-ev--full::before {
@@ -1413,7 +1420,7 @@ function onCellKeydown(e, ms) {
1413
1420
  }
1414
1421
  .wg-ev--tentative .wg-ev-title,
1415
1422
  .wg-ev--full .wg-ev-title {
1416
- color: var(--dt-text-2, rgba(0, 0, 0, 0.54));
1423
+ color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
1417
1424
  }
1418
1425
  .wg-ev--tentative::before,
1419
1426
  .wg-ev--limited::before {
@@ -1426,14 +1433,14 @@ function onCellKeydown(e, ms) {
1426
1433
  .wg-ev-time {
1427
1434
  font: 400 14px / 1 var(--dt-sans, system-ui, sans-serif);
1428
1435
  font-variant-numeric: tabular-nums;
1429
- color: var(--dt-text, rgba(0, 0, 0, 0.87));
1436
+ color: var(--dt-text, rgba(15, 15, 15, 0.87));
1430
1437
  flex-shrink: 0;
1431
1438
  white-space: nowrap;
1432
1439
  }
1433
1440
 
1434
1441
  .wg-ev-title {
1435
1442
  font: 500 15px / 1.25 var(--dt-sans, system-ui, sans-serif);
1436
- color: var(--dt-text, rgba(0, 0, 0, 0.87));
1443
+ color: var(--dt-text, rgba(15, 15, 15, 0.87));
1437
1444
  white-space: nowrap;
1438
1445
  overflow: hidden;
1439
1446
  text-overflow: ellipsis;
@@ -1443,7 +1450,7 @@ function onCellKeydown(e, ms) {
1443
1450
 
1444
1451
  .wg-ev-loc {
1445
1452
  font: 400 12.5px / 1 var(--dt-sans, system-ui, sans-serif);
1446
- color: var(--dt-text, rgba(0, 0, 0, 0.87));
1453
+ color: var(--dt-text, rgba(15, 15, 15, 0.87));
1447
1454
  white-space: nowrap;
1448
1455
  flex-shrink: 0; /* shown only when measured to fit — never squeezed */
1449
1456
  }
@@ -1456,37 +1463,36 @@ function onCellKeydown(e, ms) {
1456
1463
  border-radius: 0;
1457
1464
  text-align: left;
1458
1465
  align-self: flex-start;
1459
- font: 500 10px / 1 var(--dt-sans, system-ui, sans-serif);
1460
- color: var(--dt-text-2, rgba(0, 0, 0, 0.54));
1466
+ font: 400 12.5px / 1 var(--dt-sans, system-ui, sans-serif);
1467
+ color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
1461
1468
  padding: 2px 8px;
1462
1469
  cursor: pointer;
1463
1470
  flex-shrink: 0;
1464
- margin-top: 2px;
1465
1471
  }
1466
1472
 
1467
1473
  .wg-ev-more:hover {
1468
- color: var(--dt-text, rgba(0, 0, 0, 0.87));
1474
+ color: var(--dt-text, rgba(15, 15, 15, 0.87));
1469
1475
  }
1470
1476
 
1471
1477
  .wg-ev-more:focus-visible {
1472
1478
  outline: none;
1473
- box-shadow: 0 0 0 2px var(--dt-accent, #2563eb);
1479
+ box-shadow: 0 0 0 2px var(--dt-accent, #1d4fd7);
1474
1480
  }
1475
1481
 
1476
1482
  /* ─── Focus-visible ──────────────────────────────── */
1477
1483
  .wg-cell:focus-visible {
1478
- outline: 2px solid var(--dt-accent, #2563eb);
1484
+ outline: 2px solid var(--dt-accent, #1d4fd7);
1479
1485
  outline-offset: -2px;
1480
1486
  }
1481
1487
 
1482
1488
  .wg-ev:focus-visible {
1483
1489
  outline: none;
1484
- box-shadow: 0 0 0 2px var(--dt-accent, #2563eb);
1490
+ box-shadow: 0 0 0 2px var(--dt-accent, #1d4fd7);
1485
1491
  }
1486
1492
 
1487
1493
  .wg-ev--dragging {
1488
1494
  cursor: grabbing;
1489
- background: var(--dt-hover, rgba(0, 0, 0, 0.04));
1495
+ background: var(--dt-hover, rgba(15, 15, 15, 0.04));
1490
1496
  box-shadow: inset 0 0 0 1px var(--ev-color);
1491
1497
  }
1492
1498
  </style>