@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.
- package/README.md +143 -93
- 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 +226 -304
- package/dist/calendar/Calendar.svelte.d.ts +1 -1
- package/dist/primitives/DayHeader.svelte +7 -7
- 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 +16 -3
- package/dist/theme/presets.d.ts +2 -2
- package/dist/theme/presets.js +2 -2
- package/dist/views/agenda/AgendaDay.svelte +207 -323
- package/dist/views/agenda/AgendaWeek.svelte +145 -222
- package/dist/views/mobile/MobileDay.svelte +79 -60
- package/dist/views/mobile/MobileWeek.svelte +48 -38
- package/dist/views/month/MonthGrid.svelte +92 -36
- package/dist/views/planner/PlannerScroll.svelte +78 -72
- package/dist/views/planner/PlannerWeek.svelte +145 -90
- package/dist/views/shared/context.svelte.d.ts +2 -0
- package/dist/views/shared/context.svelte.js +1 -0
- package/dist/views/shared/format.d.ts +3 -0
- package/dist/views/shared/format.js +10 -1
- package/package.json +1 -1
- package/widget/widget.js +816 -725
|
@@ -12,6 +12,7 @@ import { createClock } from "../../core/clock.svelte.js";
|
|
|
12
12
|
import { HOUR_MS, sod, addDaysMs, diffDays, isAllDay, segmentForDay } from "../../core/time.js";
|
|
13
13
|
import { fmtHParts, fmtTime } from "../../core/locale.js";
|
|
14
14
|
import { createSwipe } from "./swipe.js";
|
|
15
|
+
import { dateLong } from "../shared/format.js";
|
|
15
16
|
let { height = null, events = [], style = "", locale, focusDate, oneventclick, oneventcreate, selectedEventId = null, readOnly = false, visibleHours } = $props();
|
|
16
17
|
// ── Context ────────────────────────────────────────
|
|
17
18
|
const ctx = useCalendarContext();
|
|
@@ -475,7 +476,7 @@ $effect(() => {
|
|
|
475
476
|
style={style || undefined}
|
|
476
477
|
style:height={autoHeight ? undefined : (height ? `${height}px` : '100%')}
|
|
477
478
|
role="region"
|
|
478
|
-
aria-label={L.dayPlanner}
|
|
479
|
+
aria-label="{L.dayPlanner}, {dateLong(dayMs, locale)}"
|
|
479
480
|
ontouchstart={swipe.ontouchstart}
|
|
480
481
|
ontouchmove={swipe.ontouchmove}
|
|
481
482
|
ontouchend={swipe.ontouchend}
|
|
@@ -580,7 +581,7 @@ $effect(() => {
|
|
|
580
581
|
style:height="{p.height}px"
|
|
581
582
|
style:left={p.left}
|
|
582
583
|
style:width={p.width}
|
|
583
|
-
style:--ev-color={p.ev.color ?? 'var(--dt-accent)'}
|
|
584
|
+
style:--ev-color={p.ev.color ?? 'var(--dt-event, var(--dt-accent))'}
|
|
584
585
|
onclick={(e) => { e.stopPropagation(); if (suppressEventClick) { suppressEventClick = false; return; } oneventclick?.(p.ev); }}
|
|
585
586
|
onpointerenter={() => oneventhover?.(p.ev)}
|
|
586
587
|
aria-label="{p.ev.title}{statusText(p.ev)}, {fmtTime(p.ev.start, locale)} – {fmtTime(p.ev.end, locale)}{p.isCurrent ? `, ${L.inProgress}` : ''}{p.isNext ? `, ${L.upNext}` : ''}"
|
|
@@ -588,11 +589,11 @@ $effect(() => {
|
|
|
588
589
|
<div class="mb-ev-stripe"></div>
|
|
589
590
|
<div class="mb-ev-body">
|
|
590
591
|
<EventContent event={p.ev}>
|
|
591
|
-
<!-- Line thresholds must track real content height (title
|
|
592
|
-
time
|
|
592
|
+
<!-- Line thresholds must track real content height (title 19 +
|
|
593
|
+
time 14 + sub 14 + loc 13 + tags 19 + padding 8) — showing
|
|
593
594
|
a line the block can't hold clips text at both ends. -->
|
|
594
595
|
<span class="mb-ev-title">{p.ev.title}</span>
|
|
595
|
-
{#if p.height >
|
|
596
|
+
{#if p.height > 36}
|
|
596
597
|
<span class="mb-ev-time">{fmtTime(p.ev.start, locale)} – {fmtTime(p.ev.end, locale)}</span>
|
|
597
598
|
{/if}
|
|
598
599
|
{#if p.ev.subtitle && p.height > 56}
|
|
@@ -670,7 +671,7 @@ $effect(() => {
|
|
|
670
671
|
user-select: none;
|
|
671
672
|
font-variant-numeric: tabular-nums;
|
|
672
673
|
overflow: hidden;
|
|
673
|
-
background: var(--dt-bg, #
|
|
674
|
+
background: var(--dt-bg, #efebe9);
|
|
674
675
|
-webkit-tap-highlight-color: transparent;
|
|
675
676
|
touch-action: pan-y pinch-zoom;
|
|
676
677
|
}
|
|
@@ -698,7 +699,7 @@ $effect(() => {
|
|
|
698
699
|
padding: 4px 8px;
|
|
699
700
|
overflow-x: auto;
|
|
700
701
|
scrollbar-width: none;
|
|
701
|
-
border-bottom: 1px solid var(--dt-border, rgba(
|
|
702
|
+
border-bottom: 1px solid var(--dt-border, rgba(15, 15, 15, 0.08));
|
|
702
703
|
flex-shrink: 0;
|
|
703
704
|
align-items: center;
|
|
704
705
|
}
|
|
@@ -744,7 +745,7 @@ $effect(() => {
|
|
|
744
745
|
}
|
|
745
746
|
.mb-allday-chip:focus-visible {
|
|
746
747
|
outline: none;
|
|
747
|
-
box-shadow: inset 0 0 0 2px var(--dt-btn-text, #fff), 0 0 0 2px var(--dt-accent, #
|
|
748
|
+
box-shadow: inset 0 0 0 2px var(--dt-btn-text, #fff), 0 0 0 2px var(--dt-accent, #1d4fd7);
|
|
748
749
|
}
|
|
749
750
|
|
|
750
751
|
/* The band is the colour; no dot. */
|
|
@@ -753,7 +754,7 @@ $effect(() => {
|
|
|
753
754
|
}
|
|
754
755
|
|
|
755
756
|
.mb-allday-title {
|
|
756
|
-
font: 500
|
|
757
|
+
font: 500 13.5px/1 var(--dt-sans, system-ui, sans-serif);
|
|
757
758
|
color: inherit;
|
|
758
759
|
white-space: nowrap;
|
|
759
760
|
max-width: 100px;
|
|
@@ -762,15 +763,15 @@ $effect(() => {
|
|
|
762
763
|
}
|
|
763
764
|
|
|
764
765
|
.mb-allday-span {
|
|
765
|
-
font: 400
|
|
766
|
+
font: 400 12.5px/1 var(--dt-sans, system-ui, sans-serif);
|
|
766
767
|
font-variant-numeric: tabular-nums;
|
|
767
768
|
color: inherit;
|
|
768
769
|
opacity: 0.75;
|
|
769
770
|
}
|
|
770
771
|
|
|
771
772
|
.mb-allday-more {
|
|
772
|
-
font:
|
|
773
|
-
color: var(--dt-text-2, rgba(
|
|
773
|
+
font: 400 12.5px/1 var(--dt-sans, system-ui, sans-serif);
|
|
774
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
774
775
|
white-space: nowrap;
|
|
775
776
|
flex-shrink: 0;
|
|
776
777
|
padding: 0 6px;
|
|
@@ -792,7 +793,7 @@ $effect(() => {
|
|
|
792
793
|
}
|
|
793
794
|
.mb-allday-more:focus-visible {
|
|
794
795
|
outline: none;
|
|
795
|
-
box-shadow: 0 0 0 2px var(--dt-accent, #
|
|
796
|
+
box-shadow: 0 0 0 2px var(--dt-accent, #1d4fd7);
|
|
796
797
|
}
|
|
797
798
|
|
|
798
799
|
/* ─── Grid ───────────────────────────────────────── */
|
|
@@ -803,14 +804,14 @@ $effect(() => {
|
|
|
803
804
|
overscroll-behavior: contain;
|
|
804
805
|
-webkit-overflow-scrolling: touch;
|
|
805
806
|
scrollbar-width: thin;
|
|
806
|
-
scrollbar-color: var(--dt-scrollbar, rgba(
|
|
807
|
+
scrollbar-color: var(--dt-scrollbar, rgba(15, 15, 15, 0.1)) transparent;
|
|
807
808
|
position: relative;
|
|
808
809
|
padding-top: 8px;
|
|
809
810
|
}
|
|
810
811
|
.mb--auto .mb-grid { overflow-y: visible; }
|
|
811
812
|
.mb-grid:focus-visible {
|
|
812
813
|
outline: none;
|
|
813
|
-
box-shadow: inset 0 0 0 2px var(--dt-accent, #
|
|
814
|
+
box-shadow: inset 0 0 0 2px var(--dt-accent, #1d4fd7);
|
|
814
815
|
}
|
|
815
816
|
|
|
816
817
|
.mb-grid-inner {
|
|
@@ -830,7 +831,7 @@ $effect(() => {
|
|
|
830
831
|
}
|
|
831
832
|
.mb-empty-text {
|
|
832
833
|
font: 500 13px/1.4 var(--dt-sans, system-ui, sans-serif);
|
|
833
|
-
color: var(--dt-text-2, rgba(
|
|
834
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
834
835
|
}
|
|
835
836
|
|
|
836
837
|
/* ─── Hour row ───────────────────────────────────── */
|
|
@@ -846,12 +847,12 @@ $effect(() => {
|
|
|
846
847
|
visibility: hidden;
|
|
847
848
|
}
|
|
848
849
|
.mb-hour-label small {
|
|
849
|
-
font-size:
|
|
850
|
-
font-weight:
|
|
850
|
+
font-size: 10px;
|
|
851
|
+
font-weight: 500;
|
|
851
852
|
vertical-align: top;
|
|
852
853
|
margin-left: 1px;
|
|
853
854
|
letter-spacing: 0;
|
|
854
|
-
color: var(--dt-text-2, rgba(
|
|
855
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
855
856
|
}
|
|
856
857
|
.mb-hour-label {
|
|
857
858
|
width: 40px;
|
|
@@ -859,11 +860,11 @@ $effect(() => {
|
|
|
859
860
|
start at — content-box pushed digits flush under the event edge */
|
|
860
861
|
box-sizing: border-box;
|
|
861
862
|
flex-shrink: 0;
|
|
862
|
-
font:
|
|
863
|
+
font: 400 15px/1 var(--dt-sans, system-ui, sans-serif);
|
|
863
864
|
font-stretch: 90%;
|
|
864
865
|
font-variant-numeric: tabular-nums;
|
|
865
866
|
letter-spacing: -0.02em;
|
|
866
|
-
color: var(--dt-text, rgba(
|
|
867
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
867
868
|
text-align: right;
|
|
868
869
|
padding-right: 8px;
|
|
869
870
|
padding-top: 0;
|
|
@@ -874,14 +875,14 @@ $effect(() => {
|
|
|
874
875
|
.mb-hour-line {
|
|
875
876
|
flex: 1;
|
|
876
877
|
height: 1px;
|
|
877
|
-
background: var(--dt-border, rgba(
|
|
878
|
+
background: var(--dt-border, rgba(15, 15, 15, 0.08));
|
|
878
879
|
}
|
|
879
880
|
|
|
880
881
|
.mb-hour--blocked {
|
|
881
882
|
background: repeating-linear-gradient(
|
|
882
883
|
-45deg,
|
|
883
|
-
color-mix(in srgb, var(--dt-text, rgba(
|
|
884
|
-
color-mix(in srgb, var(--dt-text, rgba(
|
|
884
|
+
color-mix(in srgb, var(--dt-text, rgba(15, 15, 15, 0.87)) 3%, transparent),
|
|
885
|
+
color-mix(in srgb, var(--dt-text, rgba(15, 15, 15, 0.87)) 3%, transparent) 4px,
|
|
885
886
|
transparent 4px,
|
|
886
887
|
transparent 8px
|
|
887
888
|
);
|
|
@@ -892,18 +893,20 @@ $effect(() => {
|
|
|
892
893
|
left: 44px;
|
|
893
894
|
top: 50%;
|
|
894
895
|
transform: translateY(-50%);
|
|
895
|
-
font: 500
|
|
896
|
-
color: var(--dt-text-2, rgba(
|
|
896
|
+
font: 500 11px/1 var(--dt-sans, system-ui, sans-serif);
|
|
897
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
897
898
|
text-transform: uppercase;
|
|
898
899
|
letter-spacing: 0.04em;
|
|
899
900
|
}
|
|
900
901
|
|
|
901
902
|
/* ─── Now line ───────────────────────────────────── */
|
|
903
|
+
/* No stacking context of its own: the plate and the dot sit above the
|
|
904
|
+
events, the line under them (the event it crosses is opaque), so the
|
|
905
|
+
line never strikes through a title. */
|
|
902
906
|
.mb-now {
|
|
903
907
|
position: absolute;
|
|
904
908
|
left: 0;
|
|
905
909
|
right: 0;
|
|
906
|
-
z-index: 10;
|
|
907
910
|
display: flex;
|
|
908
911
|
align-items: center;
|
|
909
912
|
pointer-events: none;
|
|
@@ -911,18 +914,32 @@ $effect(() => {
|
|
|
911
914
|
|
|
912
915
|
/* The clock is a reversed plate on the accent, as in the desktop gutter. */
|
|
913
916
|
.mb-now-label {
|
|
917
|
+
position: relative;
|
|
918
|
+
z-index: 10;
|
|
914
919
|
width: 40px;
|
|
915
920
|
box-sizing: border-box;
|
|
916
921
|
flex-shrink: 0;
|
|
917
922
|
padding: 0 4px 0 0;
|
|
918
923
|
text-align: right;
|
|
924
|
+
white-space: nowrap;
|
|
925
|
+
}
|
|
926
|
+
.mb-now-label::after {
|
|
927
|
+
content: '';
|
|
928
|
+
position: absolute;
|
|
929
|
+
right: -4px;
|
|
930
|
+
top: 50%;
|
|
931
|
+
width: 8px;
|
|
932
|
+
height: 8px;
|
|
933
|
+
margin-top: -4px;
|
|
934
|
+
border-radius: 50%;
|
|
935
|
+
background: var(--dt-accent, #1d4fd7);
|
|
919
936
|
}
|
|
920
937
|
.mb-now-label span {
|
|
921
938
|
display: inline-block;
|
|
922
939
|
padding: 2px 3px;
|
|
923
940
|
border-radius: 0;
|
|
924
|
-
background: var(--dt-accent, #
|
|
925
|
-
font:
|
|
941
|
+
background: var(--dt-accent, #1d4fd7);
|
|
942
|
+
font: 500 11px/1.2 var(--dt-sans, system-ui, sans-serif);
|
|
926
943
|
font-variant-numeric: tabular-nums;
|
|
927
944
|
color: var(--dt-btn-text, #ffffff);
|
|
928
945
|
}
|
|
@@ -930,20 +947,10 @@ $effect(() => {
|
|
|
930
947
|
.mb-now-line {
|
|
931
948
|
flex: 1;
|
|
932
949
|
height: 0;
|
|
933
|
-
border-top: 2px solid var(--dt-accent, #
|
|
950
|
+
border-top: 2px solid var(--dt-accent, #1d4fd7);
|
|
934
951
|
box-shadow: none;
|
|
935
952
|
position: relative;
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
.mb-now-line::before {
|
|
939
|
-
content: '';
|
|
940
|
-
position: absolute;
|
|
941
|
-
left: -4px;
|
|
942
|
-
top: -4px;
|
|
943
|
-
width: 10px;
|
|
944
|
-
height: 10px;
|
|
945
|
-
border-radius: 50%;
|
|
946
|
-
background: var(--dt-accent, #2563eb);
|
|
953
|
+
z-index: 4;
|
|
947
954
|
}
|
|
948
955
|
|
|
949
956
|
/* ─── Events ─────────────────────────────────────── */
|
|
@@ -954,7 +961,7 @@ $effect(() => {
|
|
|
954
961
|
cursor: pointer;
|
|
955
962
|
background: transparent;
|
|
956
963
|
border: none;
|
|
957
|
-
border-bottom: 1px solid var(--dt-border, rgba(
|
|
964
|
+
border-bottom: 1px solid var(--dt-border, rgba(15, 15, 15, 0.3));
|
|
958
965
|
box-sizing: border-box;
|
|
959
966
|
display: flex;
|
|
960
967
|
align-items: stretch;
|
|
@@ -967,7 +974,7 @@ $effect(() => {
|
|
|
967
974
|
}
|
|
968
975
|
.mb-event:hover,
|
|
969
976
|
.mb-event:active {
|
|
970
|
-
background: var(--dt-hover, rgba(
|
|
977
|
+
background: var(--dt-hover, rgba(15, 15, 15, 0.04));
|
|
971
978
|
}
|
|
972
979
|
/* Short blocks keep their duration-proportional height, but get a 44px
|
|
973
980
|
transparent hit-slop so taps still land. */
|
|
@@ -990,21 +997,33 @@ $effect(() => {
|
|
|
990
997
|
.mb-event--selected {
|
|
991
998
|
box-shadow: inset 0 0 0 1px var(--ev-color);
|
|
992
999
|
}
|
|
993
|
-
|
|
994
|
-
|
|
1000
|
+
/* The event in progress is the one the now line crosses: its wash is
|
|
1001
|
+
laid over the paper, opaque, so the line runs beneath its text. */
|
|
1002
|
+
.mb-event.mb-event--current {
|
|
1003
|
+
background:
|
|
1004
|
+
linear-gradient(var(--dt-accent-dim, rgba(29, 79, 215, 0.12)), var(--dt-accent-dim, rgba(29, 79, 215, 0.12))),
|
|
1005
|
+
var(--dt-paper, none),
|
|
1006
|
+
var(--dt-bg, #efebe9);
|
|
1007
|
+
}
|
|
1008
|
+
.mb-event.mb-event--current:hover,
|
|
1009
|
+
.mb-event.mb-event--current:active {
|
|
1010
|
+
background:
|
|
1011
|
+
linear-gradient(var(--dt-hover, rgba(15, 15, 15, 0.04)), var(--dt-hover, rgba(15, 15, 15, 0.04))),
|
|
1012
|
+
var(--dt-paper, none),
|
|
1013
|
+
var(--dt-bg, #efebe9);
|
|
995
1014
|
}
|
|
996
1015
|
/* Printed states: a cancelled class is struck through; a tentative or
|
|
997
1016
|
limited one is set in grey with a dashed bar — never a bare opacity. */
|
|
998
1017
|
.mb-event--cancelled .mb-ev-title {
|
|
999
1018
|
text-decoration: line-through;
|
|
1000
|
-
color: var(--dt-text-2, rgba(
|
|
1019
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
1001
1020
|
}
|
|
1002
1021
|
.mb-event--cancelled .mb-ev-stripe {
|
|
1003
1022
|
opacity: 0.45; /* decorative bar only */
|
|
1004
1023
|
}
|
|
1005
1024
|
.mb-event--tentative .mb-ev-title,
|
|
1006
1025
|
.mb-event--full .mb-ev-title {
|
|
1007
|
-
color: var(--dt-text-2, rgba(
|
|
1026
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
1008
1027
|
}
|
|
1009
1028
|
.mb-event--tentative .mb-ev-stripe,
|
|
1010
1029
|
.mb-event--limited .mb-ev-stripe {
|
|
@@ -1084,17 +1103,17 @@ $effect(() => {
|
|
|
1084
1103
|
right: 4px;
|
|
1085
1104
|
z-index: 40;
|
|
1086
1105
|
border-radius: 0;
|
|
1087
|
-
background: color-mix(in srgb, var(--dt-accent, #
|
|
1088
|
-
border: 1px dashed color-mix(in srgb, var(--dt-accent, #
|
|
1106
|
+
background: color-mix(in srgb, var(--dt-accent, #1d4fd7) 12%, transparent);
|
|
1107
|
+
border: 1px dashed color-mix(in srgb, var(--dt-accent, #1d4fd7) 55%, transparent);
|
|
1089
1108
|
display: flex;
|
|
1090
1109
|
align-items: flex-start;
|
|
1091
1110
|
overflow: hidden;
|
|
1092
1111
|
pointer-events: none;
|
|
1093
1112
|
}
|
|
1094
1113
|
.mb-create-ghost-time {
|
|
1095
|
-
font:
|
|
1114
|
+
font: 500 11px/1 var(--dt-sans, system-ui, sans-serif);
|
|
1096
1115
|
font-variant-numeric: tabular-nums;
|
|
1097
|
-
color: var(--dt-accent, #
|
|
1116
|
+
color: var(--dt-accent, #1d4fd7);
|
|
1098
1117
|
padding: 4px 8px;
|
|
1099
1118
|
white-space: nowrap;
|
|
1100
1119
|
}
|
|
@@ -1118,29 +1137,29 @@ $effect(() => {
|
|
|
1118
1137
|
|
|
1119
1138
|
.mb-ev-title {
|
|
1120
1139
|
font: 500 15px/1.25 var(--dt-sans, system-ui, sans-serif);
|
|
1121
|
-
color: var(--dt-text, rgba(
|
|
1140
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
1122
1141
|
white-space: nowrap;
|
|
1123
1142
|
overflow: hidden;
|
|
1124
1143
|
text-overflow: ellipsis;
|
|
1125
1144
|
}
|
|
1126
1145
|
|
|
1127
1146
|
.mb-ev-time {
|
|
1128
|
-
font: 400
|
|
1147
|
+
font: 400 14px/1 var(--dt-sans, system-ui, sans-serif);
|
|
1129
1148
|
font-variant-numeric: tabular-nums;
|
|
1130
|
-
color: var(--dt-text
|
|
1149
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
1131
1150
|
}
|
|
1132
1151
|
|
|
1133
1152
|
.mb-ev-sub {
|
|
1134
|
-
font: 400
|
|
1135
|
-
color: var(--dt-text-2, rgba(
|
|
1153
|
+
font: 400 12.5px/1.1 var(--dt-sans, system-ui, sans-serif);
|
|
1154
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
1136
1155
|
white-space: nowrap;
|
|
1137
1156
|
overflow: hidden;
|
|
1138
1157
|
text-overflow: ellipsis;
|
|
1139
1158
|
}
|
|
1140
1159
|
|
|
1141
1160
|
.mb-ev-loc {
|
|
1142
|
-
font: 400
|
|
1143
|
-
color: var(--dt-text-2, rgba(
|
|
1161
|
+
font: 400 12.5px/1 var(--dt-sans, system-ui, sans-serif);
|
|
1162
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
1144
1163
|
white-space: nowrap;
|
|
1145
1164
|
overflow: hidden;
|
|
1146
1165
|
text-overflow: ellipsis;
|
|
@@ -1178,7 +1197,7 @@ $effect(() => {
|
|
|
1178
1197
|
position: absolute;
|
|
1179
1198
|
top: 4px;
|
|
1180
1199
|
right: 4px;
|
|
1181
|
-
font:
|
|
1200
|
+
font: 500 11px/1 var(--dt-sans, system-ui, sans-serif);
|
|
1182
1201
|
color: var(--ev-color, var(--dt-accent));
|
|
1183
1202
|
background: color-mix(in srgb, var(--ev-color, var(--dt-accent)) 15%, transparent);
|
|
1184
1203
|
padding: 2px 5px;
|
|
@@ -1194,6 +1213,6 @@ $effect(() => {
|
|
|
1194
1213
|
/* ─── Focus ──────────────────────────────────────── */
|
|
1195
1214
|
.mb-event:focus-visible {
|
|
1196
1215
|
outline: none;
|
|
1197
|
-
box-shadow: 0 0 0 2px var(--dt-accent, #
|
|
1216
|
+
box-shadow: 0 0 0 2px var(--dt-accent, #1d4fd7);
|
|
1198
1217
|
}
|
|
1199
1218
|
</style>
|
|
@@ -10,7 +10,8 @@ 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, weekdayShort } from "../../core/locale.js";
|
|
13
|
+
import { fmtTime as _fmtTime, fmtWeekRange, weekdayShort } from "../../core/locale.js";
|
|
14
|
+
import { dateLong } from "../shared/format.js";
|
|
14
15
|
import { createSwipe } from "./swipe.js";
|
|
15
16
|
let { mondayStart = true, locale, height = null, events = [], style = "", focusDate, oneventclick, selectedEventId = null } = $props();
|
|
16
17
|
// ── Context ────────────────────────────────────────
|
|
@@ -52,7 +53,8 @@ const dayCells = $derived.by(() => {
|
|
|
52
53
|
const jsDay = d.getDay();
|
|
53
54
|
const isoDay = jsDay === 0 ? 7 : jsDay;
|
|
54
55
|
if (hideSet.has(isoDay)) continue;
|
|
55
|
-
|
|
56
|
+
// A dateless weekly template (showDates=false) has no today to mark.
|
|
57
|
+
const isToday = showDates && ms === todayMs;
|
|
56
58
|
const isPast = equalDays ? false : ms < todayMs;
|
|
57
59
|
const isWeekend = jsDay === 0 || jsDay === 6;
|
|
58
60
|
const isDisabled = disabledSet.has(ms);
|
|
@@ -98,7 +100,9 @@ function evTimeLabel(ev) {
|
|
|
98
100
|
/** Visible time on a day row: the start, or "until 01:00" on the day an
|
|
99
101
|
* overnight event runs into. */
|
|
100
102
|
function evRowTime(ev, dayMs) {
|
|
101
|
-
|
|
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 : "";
|
|
102
106
|
if (ev.start.getTime() < dayMs) return `${L.until} ${fmtTime(ev.end)}`;
|
|
103
107
|
return fmtTime(ev.start);
|
|
104
108
|
}
|
|
@@ -165,7 +169,9 @@ function handleDayKeydown(e, dayMs) {
|
|
|
165
169
|
style={style || undefined}
|
|
166
170
|
style:height={autoHeight ? undefined : (height ? `${height}px` : '100%')}
|
|
167
171
|
role="region"
|
|
168
|
-
aria-label={L.weekAhead}
|
|
172
|
+
aria-label="{L.weekAhead}{dayCells.length
|
|
173
|
+
? `, ${fmtWeekRange(dayCells[0].ms, locale, dayCells[dayCells.length - 1].ms)}`
|
|
174
|
+
: ''}"
|
|
169
175
|
ontouchstart={swipe.ontouchstart}
|
|
170
176
|
ontouchmove={swipe.ontouchmove}
|
|
171
177
|
ontouchend={swipe.ontouchend}
|
|
@@ -195,7 +201,7 @@ function handleDayKeydown(e, dayMs) {
|
|
|
195
201
|
disabled={cell.isDisabled}
|
|
196
202
|
onclick={() => handleDayTap(cell.ms)}
|
|
197
203
|
onkeydown={(e) => handleDayKeydown(e, cell.ms)}
|
|
198
|
-
aria-label="{cell.
|
|
204
|
+
aria-label="{dateLong(cell.ms, locale)}{cell.isToday ? `, ${L.today}` : ''}"
|
|
199
205
|
></button>
|
|
200
206
|
<!-- Date column -->
|
|
201
207
|
<div class="mw-date">
|
|
@@ -221,7 +227,7 @@ function handleDayKeydown(e, dayMs) {
|
|
|
221
227
|
class:mw-ev--tentative={ev.status === 'tentative'}
|
|
222
228
|
class:mw-ev--full={ev.status === 'full'}
|
|
223
229
|
class:mw-ev--limited={ev.status === 'limited'}
|
|
224
|
-
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))')}
|
|
225
231
|
onclick={(e) => { e.stopPropagation(); oneventclick?.(ev); }}
|
|
226
232
|
onkeydown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); e.stopPropagation(); oneventclick?.(ev); } }}
|
|
227
233
|
onpointerenter={() => oneventhover?.(ev)}
|
|
@@ -265,7 +271,7 @@ function handleDayKeydown(e, dayMs) {
|
|
|
265
271
|
user-select: none;
|
|
266
272
|
font-variant-numeric: tabular-nums;
|
|
267
273
|
overflow: hidden;
|
|
268
|
-
background: var(--dt-bg, #
|
|
274
|
+
background: var(--dt-bg, #efebe9);
|
|
269
275
|
-webkit-tap-highlight-color: transparent;
|
|
270
276
|
touch-action: pan-y pinch-zoom;
|
|
271
277
|
}
|
|
@@ -279,7 +285,7 @@ function handleDayKeydown(e, dayMs) {
|
|
|
279
285
|
overscroll-behavior: contain;
|
|
280
286
|
-webkit-overflow-scrolling: touch;
|
|
281
287
|
scrollbar-width: thin;
|
|
282
|
-
scrollbar-color: var(--dt-scrollbar, rgba(
|
|
288
|
+
scrollbar-color: var(--dt-scrollbar, rgba(15, 15, 15, 0.1)) transparent;
|
|
283
289
|
}
|
|
284
290
|
.mw--auto .mw-list { overflow-y: visible; }
|
|
285
291
|
.mw-list--animate {
|
|
@@ -305,33 +311,34 @@ function handleDayKeydown(e, dayMs) {
|
|
|
305
311
|
text-align: left;
|
|
306
312
|
width: 100%;
|
|
307
313
|
-webkit-tap-highlight-color: transparent;
|
|
308
|
-
border-bottom: 1px solid var(--dt-border, rgba(
|
|
314
|
+
border-bottom: 1px solid var(--dt-border, rgba(15, 15, 15, 0.08));
|
|
309
315
|
min-height: 56px;
|
|
310
316
|
}
|
|
311
317
|
.mw-row:last-child {
|
|
312
318
|
border-bottom: none;
|
|
313
319
|
}
|
|
314
320
|
.mw-row:has(.mw-row-target:active) {
|
|
315
|
-
background: var(--dt-hover, rgba(
|
|
321
|
+
background: var(--dt-hover, rgba(15, 15, 15, 0.04));
|
|
316
322
|
}
|
|
317
323
|
.mw-row--today {
|
|
318
|
-
background: color-mix(in srgb, var(--dt-accent, #
|
|
324
|
+
background: color-mix(in srgb, var(--dt-accent, #1d4fd7) 4%, transparent);
|
|
319
325
|
}
|
|
320
326
|
/* Token-based dim (not subtree opacity) so past rows stay legible/tappable */
|
|
321
327
|
.mw-row--past {
|
|
322
|
-
background: color-mix(in srgb, var(--dt-text, rgba(
|
|
328
|
+
background: color-mix(in srgb, var(--dt-text, rgba(15, 15, 15, 0.87)) 3%, transparent);
|
|
323
329
|
}
|
|
324
330
|
.mw-row--past :global(.mw-ev-title),
|
|
331
|
+
.mw-row--past :global(.mw-ev-time),
|
|
325
332
|
.mw-row--past .mw-day-num {
|
|
326
|
-
color: var(--dt-text-2, rgba(
|
|
333
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
327
334
|
}
|
|
328
335
|
.mw-row--disabled {
|
|
329
336
|
background-image: repeating-linear-gradient(
|
|
330
337
|
135deg,
|
|
331
338
|
transparent,
|
|
332
339
|
transparent 6px,
|
|
333
|
-
color-mix(in srgb, var(--dt-text, rgba(
|
|
334
|
-
color-mix(in srgb, var(--dt-text, rgba(
|
|
340
|
+
color-mix(in srgb, var(--dt-text, rgba(15, 15, 15, 0.87)) 4%, transparent) 6px,
|
|
341
|
+
color-mix(in srgb, var(--dt-text, rgba(15, 15, 15, 0.87)) 4%, transparent) 12px
|
|
335
342
|
);
|
|
336
343
|
}
|
|
337
344
|
.mw-row-target {
|
|
@@ -349,7 +356,7 @@ function handleDayKeydown(e, dayMs) {
|
|
|
349
356
|
}
|
|
350
357
|
.mw-row-target:focus-visible {
|
|
351
358
|
outline: none;
|
|
352
|
-
box-shadow: inset 0 0 0 2px var(--dt-accent, #
|
|
359
|
+
box-shadow: inset 0 0 0 2px var(--dt-accent, #1d4fd7);
|
|
353
360
|
}
|
|
354
361
|
|
|
355
362
|
/* ─── Date column ────────────────────────────────── */
|
|
@@ -366,22 +373,25 @@ function handleDayKeydown(e, dayMs) {
|
|
|
366
373
|
}
|
|
367
374
|
|
|
368
375
|
.mw-day-name {
|
|
369
|
-
font:
|
|
370
|
-
letter-spacing: 0.
|
|
376
|
+
font: 500 12px/1 var(--dt-sans, system-ui, sans-serif);
|
|
377
|
+
letter-spacing: 0.08em;
|
|
371
378
|
text-transform: uppercase;
|
|
372
|
-
color: var(--dt-text-2, rgba(
|
|
379
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
373
380
|
}
|
|
374
381
|
.mw-day-name--today {
|
|
375
|
-
color: var(--dt-accent, #
|
|
382
|
+
color: var(--dt-accent, #1d4fd7);
|
|
376
383
|
}
|
|
377
384
|
|
|
385
|
+
/* The date is the typography: large and regular, narrowed like the planner's */
|
|
378
386
|
.mw-day-num {
|
|
379
|
-
font:
|
|
380
|
-
|
|
387
|
+
font: 400 22px/1 var(--dt-sans, system-ui, sans-serif);
|
|
388
|
+
font-stretch: 90%;
|
|
389
|
+
font-variant-numeric: tabular-nums;
|
|
390
|
+
letter-spacing: -0.02em;
|
|
391
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
381
392
|
}
|
|
382
393
|
.mw-day-num--today {
|
|
383
|
-
color: var(--dt-accent, #
|
|
384
|
-
font-weight: 500;
|
|
394
|
+
color: var(--dt-accent, #1d4fd7);
|
|
385
395
|
}
|
|
386
396
|
|
|
387
397
|
/* ─── Events column ──────────────────────────────── */
|
|
@@ -400,7 +410,7 @@ function handleDayKeydown(e, dayMs) {
|
|
|
400
410
|
|
|
401
411
|
.mw-empty {
|
|
402
412
|
font: 400 13px/1 var(--dt-sans, system-ui, sans-serif);
|
|
403
|
-
color: var(--dt-text-2, rgba(
|
|
413
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
404
414
|
}
|
|
405
415
|
|
|
406
416
|
/* ─── Event chip ─────────────────────────────────── */
|
|
@@ -416,20 +426,20 @@ function handleDayKeydown(e, dayMs) {
|
|
|
416
426
|
transition: background 120ms;
|
|
417
427
|
-webkit-tap-highlight-color: transparent;
|
|
418
428
|
border: none;
|
|
419
|
-
border-bottom: 1px solid var(--dt-border, rgba(
|
|
429
|
+
border-bottom: 1px solid var(--dt-border, rgba(15, 15, 15, 0.3));
|
|
420
430
|
text-align: left;
|
|
421
431
|
padding: 0;
|
|
422
432
|
pointer-events: auto;
|
|
423
433
|
}
|
|
424
434
|
.mw-ev:hover,
|
|
425
435
|
.mw-ev:active {
|
|
426
|
-
background: var(--dt-hover, rgba(
|
|
436
|
+
background: var(--dt-hover, rgba(15, 15, 15, 0.04));
|
|
427
437
|
}
|
|
428
438
|
.mw-ev--selected {
|
|
429
439
|
box-shadow: inset 0 0 0 1px var(--ev-color);
|
|
430
440
|
}
|
|
431
441
|
.mw-ev--current {
|
|
432
|
-
background: var(--dt-accent-dim, rgba(
|
|
442
|
+
background: var(--dt-accent-dim, rgba(29, 79, 215, 0.12));
|
|
433
443
|
}
|
|
434
444
|
/* All day: a solid band on the event colour, no tint. */
|
|
435
445
|
.mw-ev--allday {
|
|
@@ -453,14 +463,14 @@ function handleDayKeydown(e, dayMs) {
|
|
|
453
463
|
limited one is set in grey with a dashed bar — never a bare opacity. */
|
|
454
464
|
.mw-ev--cancelled .mw-ev-title {
|
|
455
465
|
text-decoration: line-through;
|
|
456
|
-
color: var(--dt-text-2, rgba(
|
|
466
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
457
467
|
}
|
|
458
468
|
.mw-ev--cancelled .mw-ev-stripe {
|
|
459
469
|
opacity: 0.45; /* decorative bar only */
|
|
460
470
|
}
|
|
461
471
|
.mw-ev--tentative .mw-ev-title,
|
|
462
472
|
.mw-ev--full .mw-ev-title {
|
|
463
|
-
color: var(--dt-text-2, rgba(
|
|
473
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
464
474
|
}
|
|
465
475
|
.mw-ev--tentative .mw-ev-stripe,
|
|
466
476
|
.mw-ev--limited .mw-ev-stripe {
|
|
@@ -493,7 +503,7 @@ function handleDayKeydown(e, dayMs) {
|
|
|
493
503
|
|
|
494
504
|
.mw-ev-title {
|
|
495
505
|
font: 500 15px/1.25 var(--dt-sans, system-ui, sans-serif);
|
|
496
|
-
color: var(--dt-text, rgba(
|
|
506
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
497
507
|
white-space: nowrap;
|
|
498
508
|
overflow: hidden;
|
|
499
509
|
text-overflow: ellipsis;
|
|
@@ -502,16 +512,16 @@ function handleDayKeydown(e, dayMs) {
|
|
|
502
512
|
}
|
|
503
513
|
|
|
504
514
|
.mw-ev-time {
|
|
505
|
-
font: 400
|
|
515
|
+
font: 400 14px/1 var(--dt-sans, system-ui, sans-serif);
|
|
506
516
|
font-variant-numeric: tabular-nums;
|
|
507
|
-
color: var(--dt-text
|
|
517
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
508
518
|
white-space: nowrap;
|
|
509
519
|
flex-shrink: 0;
|
|
510
520
|
}
|
|
511
521
|
|
|
512
522
|
.mw-ev-more {
|
|
513
|
-
font:
|
|
514
|
-
color: var(--dt-text-2, rgba(
|
|
523
|
+
font: 400 12.5px/1 var(--dt-sans, system-ui, sans-serif);
|
|
524
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
515
525
|
padding: 2px 4px;
|
|
516
526
|
min-height: 32px;
|
|
517
527
|
border: none;
|
|
@@ -535,13 +545,13 @@ function handleDayKeydown(e, dayMs) {
|
|
|
535
545
|
}
|
|
536
546
|
.mw-ev-more:focus-visible {
|
|
537
547
|
outline: none;
|
|
538
|
-
box-shadow: 0 0 0 2px var(--dt-accent, #
|
|
548
|
+
box-shadow: 0 0 0 2px var(--dt-accent, #1d4fd7);
|
|
539
549
|
}
|
|
540
550
|
|
|
541
551
|
/* ─── Chevron ────────────────────────────────────── */
|
|
542
552
|
.mw-chevron {
|
|
543
553
|
flex-shrink: 0;
|
|
544
|
-
color: var(--dt-text-3, rgba(
|
|
554
|
+
color: var(--dt-text-3, rgba(15, 15, 15, 0.38));
|
|
545
555
|
position: relative;
|
|
546
556
|
z-index: 1;
|
|
547
557
|
pointer-events: none;
|
|
@@ -550,6 +560,6 @@ function handleDayKeydown(e, dayMs) {
|
|
|
550
560
|
/* ─── Focus ──────────────────────────────────────── */
|
|
551
561
|
.mw-ev:focus-visible {
|
|
552
562
|
outline: none;
|
|
553
|
-
box-shadow: 0 0 0 2px var(--dt-accent, #
|
|
563
|
+
box-shadow: 0 0 0 2px var(--dt-accent, #1d4fd7);
|
|
554
564
|
}
|
|
555
565
|
</style>
|