@nomideusz/svelte-calendar 1.3.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 +140 -90
- 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 +32 -16
- 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/views/agenda/AgendaDay.svelte +71 -71
- package/dist/views/agenda/AgendaWeek.svelte +48 -47
- package/dist/views/mobile/MobileDay.svelte +34 -34
- package/dist/views/mobile/MobileWeek.svelte +32 -29
- package/dist/views/month/MonthGrid.svelte +44 -19
- package/dist/views/planner/PlannerScroll.svelte +45 -45
- package/dist/views/planner/PlannerWeek.svelte +100 -72
- 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 +239 -166
package/dist/adapters/mapped.js
CHANGED
|
@@ -139,15 +139,18 @@ function collectData(raw, mappedKeys, include) {
|
|
|
139
139
|
* ```
|
|
140
140
|
*/
|
|
141
141
|
export function createMappedAdapter(sourceData, options = {}) {
|
|
142
|
-
const { fields, mapEvent: customMapper, includeData = '*', autoColor =
|
|
142
|
+
const { fields, mapEvent: customMapper, includeData = '*', autoColor = false, palette = autoColor ? VIVID_PALETTE : undefined, readOnly = true, } = options;
|
|
143
143
|
// Build the internal event list
|
|
144
144
|
const events = [];
|
|
145
145
|
const colorAssignments = new Map();
|
|
146
146
|
let colorIndex = 0;
|
|
147
147
|
function resolveColor(ev) {
|
|
148
|
-
//
|
|
148
|
+
// autoColor: always assign from the palette (ignore source color).
|
|
149
|
+
// Otherwise keep the source color; fill only when a palette is given.
|
|
149
150
|
if (!autoColor && ev.color)
|
|
150
151
|
return ev.color;
|
|
152
|
+
if (!palette?.length)
|
|
153
|
+
return ev.color;
|
|
151
154
|
const key = ev.category ?? ev.title;
|
|
152
155
|
if (!colorAssignments.has(key)) {
|
|
153
156
|
colorAssignments.set(key, palette[colorIndex % palette.length]);
|
|
@@ -2,21 +2,22 @@
|
|
|
2
2
|
* In-memory adapter — the default for demos and testing.
|
|
3
3
|
*
|
|
4
4
|
* Events are stored in a plain array. No persistence across page loads.
|
|
5
|
-
* Events without a `color`
|
|
6
|
-
*
|
|
5
|
+
* Events without a `color` stay uncoloured and draw in `--dt-event` (ink).
|
|
6
|
+
* Pass `palette` to auto-assign colours instead, grouped by `category` or
|
|
7
|
+
* `title` so related events share one.
|
|
7
8
|
*
|
|
8
9
|
* Usage:
|
|
9
10
|
* import { createMemoryAdapter } from './';
|
|
10
11
|
* const adapter = createMemoryAdapter(initialEvents);
|
|
11
|
-
* const adapter = createMemoryAdapter(initialEvents, { palette:
|
|
12
|
+
* const adapter = createMemoryAdapter(initialEvents, { palette: VIVID_PALETTE });
|
|
12
13
|
*/
|
|
13
14
|
import type { TimelineEvent } from '../core/types.js';
|
|
14
15
|
import type { CalendarAdapter } from './types.js';
|
|
15
16
|
export interface MemoryAdapterOptions {
|
|
16
17
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
18
|
+
* Colour palette for auto-colouring events that have no `color`.
|
|
19
|
+
* Off by default (events draw in `--dt-event`). Pass `VIVID_PALETTE`
|
|
20
|
+
* for the pre-1.4 look, or `generatePalette(accent)` for theme-harmonious colours.
|
|
20
21
|
*/
|
|
21
22
|
palette?: readonly string[];
|
|
22
23
|
}
|
package/dist/adapters/memory.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { VIVID_PALETTE } from '../core/palette.js';
|
|
2
1
|
import { overlapsRange } from '../core/time.js';
|
|
3
2
|
import { EventNotFoundError } from './errors.js';
|
|
4
3
|
let counter = 0;
|
|
@@ -7,12 +6,12 @@ function uid() {
|
|
|
7
6
|
}
|
|
8
7
|
export function createMemoryAdapter(initial = [], options) {
|
|
9
8
|
const events = [...initial];
|
|
10
|
-
const palette = options?.palette
|
|
11
|
-
//
|
|
9
|
+
const palette = options?.palette;
|
|
10
|
+
// Opt-in auto-color: assign from the palette by category/title
|
|
12
11
|
const colorAssignments = new Map();
|
|
13
12
|
let colorIndex = 0;
|
|
14
13
|
function resolveColor(ev) {
|
|
15
|
-
if (ev.color)
|
|
14
|
+
if (ev.color || !palette?.length)
|
|
16
15
|
return ev.color;
|
|
17
16
|
const key = ev.category ?? ev.title;
|
|
18
17
|
if (!colorAssignments.has(key)) {
|
|
@@ -74,10 +74,10 @@ export interface RecurringAdapterOptions {
|
|
|
74
74
|
/** Start weeks on Monday (default: true) */
|
|
75
75
|
mondayStart?: boolean;
|
|
76
76
|
/**
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
77
|
+
* Colour palette for auto-colouring events that have no `color`.
|
|
78
|
+
* Off by default (events draw in `--dt-event`). Pass `VIVID_PALETTE`
|
|
79
|
+
* for the pre-1.4 look, `generatePalette('#yourAccent')` for
|
|
80
|
+
* theme-harmonious colours, or your own array of colours.
|
|
81
81
|
*/
|
|
82
82
|
palette?: readonly string[];
|
|
83
83
|
/**
|
|
@@ -95,8 +95,8 @@ export interface RecurringAdapterOptions {
|
|
|
95
95
|
* Create a CalendarAdapter that projects recurring events onto concrete
|
|
96
96
|
* dates for whatever range the calendar requests.
|
|
97
97
|
*
|
|
98
|
-
* Events without a `color`
|
|
99
|
-
* grouped by `category` or `title
|
|
98
|
+
* Events without a `color` draw in `--dt-event` (ink) unless `palette` is
|
|
99
|
+
* given; then they are auto-assigned one, grouped by `category` or `title`.
|
|
100
100
|
*
|
|
101
101
|
* Read-only by default — create/update/delete throw.
|
|
102
102
|
*/
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { startOfWeek, addDaysMs, diffDays, DAY_MS, overlapsRange } from '../core/time.js';
|
|
2
|
-
import { VIVID_PALETTE } from '../core/palette.js';
|
|
3
2
|
import { CalendarReadOnlyError, EventNotFoundError } from './errors.js';
|
|
4
3
|
// ── Helpers ─────────────────────────────────────────────
|
|
5
4
|
/** Parse "HH:MM" into [hours, minutes] */
|
|
@@ -234,32 +233,31 @@ function projectMonthly(rec, range, startDate, effectiveUntil, out) {
|
|
|
234
233
|
}
|
|
235
234
|
}
|
|
236
235
|
// ── Adapter factory ─────────────────────────────────────
|
|
237
|
-
/** Default palette for auto-coloring */
|
|
238
|
-
const PALETTE = VIVID_PALETTE;
|
|
239
236
|
/**
|
|
240
237
|
* Create a CalendarAdapter that projects recurring events onto concrete
|
|
241
238
|
* dates for whatever range the calendar requests.
|
|
242
239
|
*
|
|
243
|
-
* Events without a `color`
|
|
244
|
-
* grouped by `category` or `title
|
|
240
|
+
* Events without a `color` draw in `--dt-event` (ink) unless `palette` is
|
|
241
|
+
* given; then they are auto-assigned one, grouped by `category` or `title`.
|
|
245
242
|
*
|
|
246
243
|
* Read-only by default — create/update/delete throw.
|
|
247
244
|
*/
|
|
248
245
|
export function createRecurringAdapter(schedule, options = {}) {
|
|
249
246
|
const { mondayStart = true, palette, movable = false } = options;
|
|
250
|
-
const colors = palette?.length ? palette :
|
|
247
|
+
const colors = palette?.length ? palette : undefined;
|
|
251
248
|
// Auto-color: assign from palette by category/title
|
|
252
249
|
const colorAssignments = new Map();
|
|
253
250
|
let colorIndex = 0;
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
colorAssignments.
|
|
260
|
-
|
|
251
|
+
if (colors)
|
|
252
|
+
for (const rec of schedule) {
|
|
253
|
+
if (rec.color)
|
|
254
|
+
continue;
|
|
255
|
+
const key = rec.category ?? rec.title;
|
|
256
|
+
if (!colorAssignments.has(key)) {
|
|
257
|
+
colorAssignments.set(key, colors[colorIndex % colors.length]);
|
|
258
|
+
colorIndex++;
|
|
259
|
+
}
|
|
261
260
|
}
|
|
262
|
-
}
|
|
263
261
|
function resolveColor(rec) {
|
|
264
262
|
if (rec.color)
|
|
265
263
|
return rec.color;
|
|
@@ -376,6 +376,7 @@ setContext("calendar", {
|
|
|
376
376
|
get labels() {
|
|
377
377
|
return mergedLabels;
|
|
378
378
|
},
|
|
379
|
+
announce,
|
|
379
380
|
// Load range (read/write)
|
|
380
381
|
get loadRange() {
|
|
381
382
|
return viewLoadRange;
|
|
@@ -479,6 +480,17 @@ const dateLabel = $derived.by(() => {
|
|
|
479
480
|
year: "numeric"
|
|
480
481
|
});
|
|
481
482
|
});
|
|
483
|
+
// ── Polite announcements (views say why an action did nothing) ──
|
|
484
|
+
// Shares the header's status line; a note lasts until the range changes.
|
|
485
|
+
let note = $state(null);
|
|
486
|
+
function announce(text) {
|
|
487
|
+
// A repeated message must change the text node to be read again.
|
|
488
|
+
note = {
|
|
489
|
+
text: note?.text === text ? `${text}\u00a0` : text,
|
|
490
|
+
label: dateLabel
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
const noteText = $derived(note && note.label === dateLabel ? note.text : "");
|
|
482
494
|
// ── Period title (the built-in header's big line) ──
|
|
483
495
|
// Names the month the user is looking at: "October 2026"; a week across two
|
|
484
496
|
// months reads "Oct – Nov 2026"; a day gives its date. `dateLabel` keeps the
|
|
@@ -656,7 +668,7 @@ const navCtx = $derived({
|
|
|
656
668
|
<div class="cal-hd" class:cal-hd--mobile={useMobile} class:cal-hd--stack={stackHeader}>
|
|
657
669
|
<!-- The visible title names the month; the status line announces the exact range -->
|
|
658
670
|
<span class="cal-hd-title" aria-hidden="true">{periodTitle}</span>
|
|
659
|
-
<span class="cal-sr" role="status" aria-live="polite" aria-atomic="true">{dateLabel}</span>
|
|
671
|
+
<span class="cal-sr" role="status" aria-live="polite" aria-atomic="true">{noteText || dateLabel}</span>
|
|
660
672
|
{#if showModePills && !useMobile && labelsForMode.length > 1}
|
|
661
673
|
<!-- View-type switcher (e.g. Planner ↔ Agenda) for the current mode -->
|
|
662
674
|
<div class="cal-pills cal-pills--labels" role="radiogroup" aria-label={L.viewMode}>
|
|
@@ -715,6 +727,10 @@ const navCtx = $derived({
|
|
|
715
727
|
</div>
|
|
716
728
|
{/if}
|
|
717
729
|
|
|
730
|
+
{#if headerSnippet || !(showNavigation || (showModePills && modes.length > 1) || dateLabel)}
|
|
731
|
+
<span class="cal-sr" role="status" aria-live="polite" aria-atomic="true">{noteText}</span>
|
|
732
|
+
{/if}
|
|
733
|
+
|
|
718
734
|
<div class="cal-body">
|
|
719
735
|
{#if activeView}
|
|
720
736
|
{@const Comp = activeView.component}
|
|
@@ -755,7 +771,7 @@ const navCtx = $derived({
|
|
|
755
771
|
overflow: clip;
|
|
756
772
|
display: flex;
|
|
757
773
|
flex-direction: column;
|
|
758
|
-
border: 1px solid var(--dt-border, rgba(
|
|
774
|
+
border: 1px solid var(--dt-border, rgba(15, 15, 15, 0.08));
|
|
759
775
|
box-sizing: border-box;
|
|
760
776
|
}
|
|
761
777
|
.cal--auto {
|
|
@@ -775,11 +791,11 @@ const navCtx = $derived({
|
|
|
775
791
|
align-items: center;
|
|
776
792
|
gap: 10px 24px;
|
|
777
793
|
padding: 14px 16px 12px;
|
|
778
|
-
border-bottom: 1px solid var(--dt-border, rgba(
|
|
794
|
+
border-bottom: 1px solid var(--dt-border, rgba(15, 15, 15, 0.08));
|
|
779
795
|
flex-shrink: 0;
|
|
780
796
|
box-sizing: border-box;
|
|
781
797
|
font-family: var(--dt-sans, system-ui, sans-serif);
|
|
782
|
-
color: var(--dt-text, rgba(
|
|
798
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
783
799
|
}
|
|
784
800
|
|
|
785
801
|
.cal-hd-title {
|
|
@@ -819,10 +835,10 @@ const navCtx = $derived({
|
|
|
819
835
|
.cal-hd-btn {
|
|
820
836
|
box-sizing: border-box;
|
|
821
837
|
height: var(--cal-ctl-h);
|
|
822
|
-
border: 2px solid var(--dt-text, rgba(
|
|
838
|
+
border: 2px solid var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
823
839
|
border-radius: var(--cal-ctl-r);
|
|
824
840
|
background: transparent;
|
|
825
|
-
color: var(--dt-text, rgba(
|
|
841
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
826
842
|
cursor: pointer;
|
|
827
843
|
transition: background-color 120ms, opacity 120ms;
|
|
828
844
|
-webkit-tap-highlight-color: transparent;
|
|
@@ -848,7 +864,7 @@ const navCtx = $derived({
|
|
|
848
864
|
}
|
|
849
865
|
.cal-hd-today:active:not(:disabled),
|
|
850
866
|
.cal-hd-btn:active {
|
|
851
|
-
background: color-mix(in srgb, var(--dt-text, #
|
|
867
|
+
background: color-mix(in srgb, var(--dt-text, #0f0f0f) 12%, transparent);
|
|
852
868
|
}
|
|
853
869
|
/* Today is already in view: the frame stays, quietly */
|
|
854
870
|
.cal-hd-today:disabled {
|
|
@@ -859,7 +875,7 @@ const navCtx = $derived({
|
|
|
859
875
|
.cal-hd-today:focus-visible,
|
|
860
876
|
.cal-hd-btn:focus-visible,
|
|
861
877
|
.cal-pill:focus-visible {
|
|
862
|
-
outline: 2px solid var(--dt-text, rgba(
|
|
878
|
+
outline: 2px solid var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
863
879
|
outline-offset: 2px;
|
|
864
880
|
}
|
|
865
881
|
|
|
@@ -875,12 +891,12 @@ const navCtx = $derived({
|
|
|
875
891
|
align-self: stretch;
|
|
876
892
|
align-items: center;
|
|
877
893
|
padding-inline-start: 24px;
|
|
878
|
-
border-inline-start: 1px solid var(--dt-border, rgba(
|
|
894
|
+
border-inline-start: 1px solid var(--dt-border, rgba(15, 15, 15, 0.12));
|
|
879
895
|
}
|
|
880
896
|
.cal-pill {
|
|
881
897
|
border: none;
|
|
882
898
|
background: transparent;
|
|
883
|
-
color: var(--dt-text-2, rgba(
|
|
899
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
884
900
|
cursor: pointer;
|
|
885
901
|
font: 400 15px/1 var(--dt-sans, system-ui, sans-serif);
|
|
886
902
|
min-height: var(--cal-ctl-h);
|
|
@@ -896,11 +912,11 @@ const navCtx = $derived({
|
|
|
896
912
|
}
|
|
897
913
|
/* :not(--active) — iOS keeps :hover stuck after a tap */
|
|
898
914
|
.cal-pill:hover:not(.cal-pill--active) {
|
|
899
|
-
color: var(--dt-text, rgba(
|
|
900
|
-
text-decoration-color: var(--dt-border-day, var(--dt-border, rgba(
|
|
915
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
916
|
+
text-decoration-color: var(--dt-border-day, var(--dt-border, rgba(15, 15, 15, 0.3)));
|
|
901
917
|
}
|
|
902
918
|
.cal-pill--active {
|
|
903
|
-
color: var(--dt-text, rgba(
|
|
919
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
904
920
|
text-decoration-color: currentColor;
|
|
905
921
|
}
|
|
906
922
|
|
|
@@ -962,7 +978,7 @@ const navCtx = $derived({
|
|
|
962
978
|
justify-content: center;
|
|
963
979
|
height: 100%;
|
|
964
980
|
font: 400 13px / 1 var(--dt-sans, system-ui, sans-serif);
|
|
965
|
-
color: var(--dt-text-3, rgba(
|
|
981
|
+
color: var(--dt-text-3, rgba(15, 15, 15, 0.38));
|
|
966
982
|
}
|
|
967
983
|
|
|
968
984
|
.cal-loading {
|
|
@@ -974,7 +990,7 @@ const navCtx = $derived({
|
|
|
974
990
|
background: linear-gradient(
|
|
975
991
|
90deg,
|
|
976
992
|
transparent 0%,
|
|
977
|
-
var(--dt-accent, #
|
|
993
|
+
var(--dt-accent, #1d4fd7) 50%,
|
|
978
994
|
transparent 100%
|
|
979
995
|
);
|
|
980
996
|
animation: cal-slide 1.2s ease-in-out infinite;
|
|
@@ -988,7 +1004,7 @@ const navCtx = $derived({
|
|
|
988
1004
|
@media (prefers-reduced-motion: reduce) {
|
|
989
1005
|
.cal-loading {
|
|
990
1006
|
animation: none;
|
|
991
|
-
background: var(--dt-accent-dim, rgba(
|
|
1007
|
+
background: var(--dt-accent-dim, rgba(29, 79, 215, 0.12));
|
|
992
1008
|
}
|
|
993
1009
|
}
|
|
994
1010
|
|
|
@@ -69,7 +69,7 @@ export interface CalendarProps {
|
|
|
69
69
|
mondayStart?: boolean;
|
|
70
70
|
/** Total height. Use `'auto'` to let content determine height (ideal for Agenda views). */
|
|
71
71
|
height?: number | 'auto';
|
|
72
|
-
/** Border radius in px (default:
|
|
72
|
+
/** Border radius in px (default: 0, square-cut). */
|
|
73
73
|
borderRadius?: number;
|
|
74
74
|
/** Text direction: 'ltr' (default), 'rtl', or 'auto' */
|
|
75
75
|
dir?: 'ltr' | 'rtl' | 'auto';
|
|
@@ -43,18 +43,18 @@ const dayNum = $derived(new Date(dayMs).getDate());
|
|
|
43
43
|
font: 500 10px / 1 var(--dt-sans, system-ui, sans-serif);
|
|
44
44
|
letter-spacing: 0.04em;
|
|
45
45
|
text-transform: uppercase;
|
|
46
|
-
color: var(--dt-text-2, rgba(
|
|
46
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
47
47
|
}
|
|
48
48
|
.dh-name-long {
|
|
49
49
|
font-size: 12px;
|
|
50
50
|
text-transform: none;
|
|
51
51
|
letter-spacing: 0.01em;
|
|
52
|
-
color: var(--dt-text, rgba(
|
|
52
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
.dh-num {
|
|
56
56
|
font: 600 14px / 1 var(--dt-sans, system-ui, sans-serif);
|
|
57
|
-
color: var(--dt-text, rgba(
|
|
57
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
58
58
|
width: 28px;
|
|
59
59
|
height: 28px;
|
|
60
60
|
display: flex;
|
|
@@ -63,20 +63,20 @@ const dayNum = $derived(new Date(dayMs).getDate());
|
|
|
63
63
|
border-radius: 50%;
|
|
64
64
|
}
|
|
65
65
|
.dh-num-today {
|
|
66
|
-
background: var(--dt-accent, #
|
|
66
|
+
background: var(--dt-accent, #1d4fd7);
|
|
67
67
|
color: var(--dt-btn-text, #fff);
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
.dh-date {
|
|
71
71
|
font: 400 10px / 1 var(--dt-sans, system-ui, sans-serif);
|
|
72
|
-
color: var(--dt-text-2, rgba(
|
|
72
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
.dh-rel {
|
|
76
76
|
font: 500 12px / 1.3 var(--dt-sans, system-ui, sans-serif);
|
|
77
|
-
color: var(--dt-text, rgba(
|
|
77
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
78
78
|
}
|
|
79
79
|
.dh-today .dh-rel {
|
|
80
|
-
color: var(--dt-accent, #
|
|
80
|
+
color: var(--dt-accent, #1d4fd7);
|
|
81
81
|
}
|
|
82
82
|
</style>
|
|
@@ -49,13 +49,13 @@ function handleKeydown(e) {
|
|
|
49
49
|
min-height: 24px;
|
|
50
50
|
}
|
|
51
51
|
.es:hover {
|
|
52
|
-
border-color: var(--dt-accent-dim, rgba(
|
|
53
|
-
background: var(--dt-accent-dim, rgba(
|
|
52
|
+
border-color: var(--dt-accent-dim, rgba(29, 79, 215, 0.12));
|
|
53
|
+
background: var(--dt-accent-dim, rgba(29, 79, 215, 0.12));
|
|
54
54
|
}
|
|
55
55
|
.es:focus-visible {
|
|
56
|
-
outline: 2px solid var(--dt-accent, #
|
|
56
|
+
outline: 2px solid var(--dt-accent, #1d4fd7);
|
|
57
57
|
outline-offset: 2px;
|
|
58
|
-
border-color: var(--dt-accent-dim, rgba(
|
|
58
|
+
border-color: var(--dt-accent-dim, rgba(29, 79, 215, 0.12));
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
.es-hint {
|
|
@@ -74,12 +74,12 @@ function handleKeydown(e) {
|
|
|
74
74
|
|
|
75
75
|
.es-plus {
|
|
76
76
|
font: 500 14px / 1 var(--dt-sans, system-ui, sans-serif);
|
|
77
|
-
color: var(--dt-accent, #
|
|
77
|
+
color: var(--dt-accent, #1d4fd7);
|
|
78
78
|
}
|
|
79
79
|
.es-range {
|
|
80
80
|
font: 400 10px / 1 var(--dt-sans, system-ui, sans-serif);
|
|
81
81
|
font-variant-numeric: tabular-nums;
|
|
82
|
-
color: var(--dt-text-2, rgba(
|
|
82
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
.es-v {
|
|
@@ -14,7 +14,7 @@ import { getContext } from "svelte";
|
|
|
14
14
|
const calendarCtx = getContext("calendar");
|
|
15
15
|
const L = $derived(calendarCtx?.labels ?? getLabels());
|
|
16
16
|
let { event, variant = "chip", active = false, past = false, showTime = false, showDuration = false, editable = false, onclick, children } = $props();
|
|
17
|
-
const accentColor = $derived(event.color || "var(--dt-
|
|
17
|
+
const accentColor = $derived(event.color || "var(--dt-event, var(--dt-accent))");
|
|
18
18
|
const isCancelled = $derived(event.status === "cancelled");
|
|
19
19
|
const isTentative = $derived(event.status === "tentative");
|
|
20
20
|
const isFull = $derived(event.status === "full");
|
|
@@ -145,7 +145,7 @@ function handleKeydown(e) {
|
|
|
145
145
|
|
|
146
146
|
<style>
|
|
147
147
|
.eb {
|
|
148
|
-
--_color: var(--eb-color, var(--dt-accent, #
|
|
148
|
+
--_color: var(--eb-color, var(--dt-accent, #1d4fd7));
|
|
149
149
|
cursor: default;
|
|
150
150
|
transition: opacity 120ms, transform 80ms;
|
|
151
151
|
}
|
|
@@ -156,7 +156,7 @@ function handleKeydown(e) {
|
|
|
156
156
|
transform: translateY(-1px);
|
|
157
157
|
}
|
|
158
158
|
.eb:focus-visible {
|
|
159
|
-
outline: 2px solid var(--dt-accent, #
|
|
159
|
+
outline: 2px solid var(--dt-accent, #1d4fd7);
|
|
160
160
|
outline-offset: 2px;
|
|
161
161
|
border-radius: 4px;
|
|
162
162
|
}
|
|
@@ -195,7 +195,7 @@ function handleKeydown(e) {
|
|
|
195
195
|
align-items: center;
|
|
196
196
|
gap: 5px;
|
|
197
197
|
font: 400 11px / 1 var(--dt-sans, system-ui, sans-serif);
|
|
198
|
-
color: var(--dt-text, rgba(
|
|
198
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
199
199
|
white-space: nowrap;
|
|
200
200
|
overflow: hidden;
|
|
201
201
|
text-overflow: ellipsis;
|
|
@@ -221,8 +221,8 @@ function handleKeydown(e) {
|
|
|
221
221
|
.eb-card {
|
|
222
222
|
display: flex;
|
|
223
223
|
border-radius: 8px;
|
|
224
|
-
background: var(--dt-surface, var(--dt-bg, #
|
|
225
|
-
border: 1px solid var(--dt-border, rgba(
|
|
224
|
+
background: var(--dt-surface, var(--dt-bg, #efebe9));
|
|
225
|
+
border: 1px solid var(--dt-border, rgba(15, 15, 15, 0.08));
|
|
226
226
|
overflow: hidden;
|
|
227
227
|
}
|
|
228
228
|
.eb-card .eb-stripe {
|
|
@@ -239,7 +239,7 @@ function handleKeydown(e) {
|
|
|
239
239
|
}
|
|
240
240
|
.eb-card .eb-title {
|
|
241
241
|
font: 500 12px / 1.3 var(--dt-sans, system-ui, sans-serif);
|
|
242
|
-
color: var(--dt-text, rgba(
|
|
242
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
243
243
|
overflow: hidden;
|
|
244
244
|
text-overflow: ellipsis;
|
|
245
245
|
white-space: nowrap;
|
|
@@ -247,11 +247,11 @@ function handleKeydown(e) {
|
|
|
247
247
|
.eb-card .eb-time {
|
|
248
248
|
font: 400 10px / 1 var(--dt-sans, system-ui, sans-serif);
|
|
249
249
|
font-variant-numeric: tabular-nums;
|
|
250
|
-
color: var(--dt-text-2, rgba(
|
|
250
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
251
251
|
}
|
|
252
252
|
.eb-card .eb-dur {
|
|
253
253
|
font: 300 10px / 1 var(--dt-sans, system-ui, sans-serif);
|
|
254
|
-
color: var(--dt-text-3, rgba(
|
|
254
|
+
color: var(--dt-text-3, rgba(15, 15, 15, 0.38));
|
|
255
255
|
}
|
|
256
256
|
|
|
257
257
|
/* ── Row ── */
|
|
@@ -260,7 +260,7 @@ function handleKeydown(e) {
|
|
|
260
260
|
align-items: center;
|
|
261
261
|
gap: 10px;
|
|
262
262
|
padding: 6px 12px;
|
|
263
|
-
border-bottom: 1px solid var(--dt-border, rgba(
|
|
263
|
+
border-bottom: 1px solid var(--dt-border, rgba(15, 15, 15, 0.08));
|
|
264
264
|
}
|
|
265
265
|
.eb-row .eb-stripe {
|
|
266
266
|
width: 3px;
|
|
@@ -273,13 +273,13 @@ function handleKeydown(e) {
|
|
|
273
273
|
.eb-row .eb-time {
|
|
274
274
|
font: 400 10px / 1 var(--dt-sans, system-ui, sans-serif);
|
|
275
275
|
font-variant-numeric: tabular-nums;
|
|
276
|
-
color: var(--dt-text-2, rgba(
|
|
276
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
277
277
|
flex-shrink: 0;
|
|
278
278
|
width: 90px;
|
|
279
279
|
}
|
|
280
280
|
.eb-row .eb-title {
|
|
281
281
|
font: 400 12px / 1.3 var(--dt-sans, system-ui, sans-serif);
|
|
282
|
-
color: var(--dt-text, rgba(
|
|
282
|
+
color: var(--dt-text, rgba(15, 15, 15, 0.87));
|
|
283
283
|
flex: 1;
|
|
284
284
|
overflow: hidden;
|
|
285
285
|
text-overflow: ellipsis;
|
|
@@ -287,14 +287,14 @@ function handleKeydown(e) {
|
|
|
287
287
|
}
|
|
288
288
|
.eb-row .eb-dur {
|
|
289
289
|
font: 300 10px / 1 var(--dt-sans, system-ui, sans-serif);
|
|
290
|
-
color: var(--dt-text-3, rgba(
|
|
290
|
+
color: var(--dt-text-3, rgba(15, 15, 15, 0.38));
|
|
291
291
|
flex-shrink: 0;
|
|
292
292
|
}
|
|
293
293
|
|
|
294
294
|
/* ── Shared ── */
|
|
295
295
|
.eb-subtitle {
|
|
296
296
|
font: 400 10px / 1.2 var(--dt-sans, system-ui, sans-serif);
|
|
297
|
-
color: var(--dt-text-2, rgba(
|
|
297
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
298
298
|
overflow: hidden;
|
|
299
299
|
text-overflow: ellipsis;
|
|
300
300
|
white-space: nowrap;
|
|
@@ -316,7 +316,7 @@ function handleKeydown(e) {
|
|
|
316
316
|
}
|
|
317
317
|
.eb-location {
|
|
318
318
|
font: 400 9px / 1.2 var(--dt-sans, system-ui, sans-serif);
|
|
319
|
-
color: var(--dt-text-3, rgba(
|
|
319
|
+
color: var(--dt-text-3, rgba(15, 15, 15, 0.38));
|
|
320
320
|
overflow: hidden;
|
|
321
321
|
text-overflow: ellipsis;
|
|
322
322
|
white-space: nowrap;
|
|
@@ -332,16 +332,16 @@ function handleKeydown(e) {
|
|
|
332
332
|
width: fit-content;
|
|
333
333
|
}
|
|
334
334
|
.eb-cancelled-badge {
|
|
335
|
-
color: var(--dt-text-2, rgba(
|
|
336
|
-
background: color-mix(in srgb, var(--dt-text-2, rgba(
|
|
335
|
+
color: var(--dt-text-2, rgba(15, 15, 15, 0.54));
|
|
336
|
+
background: color-mix(in srgb, var(--dt-text-2, rgba(15, 15, 15, 0.54)) 15%, transparent);
|
|
337
337
|
}
|
|
338
338
|
.eb-tentative-badge {
|
|
339
339
|
color: var(--_color);
|
|
340
340
|
background: color-mix(in srgb, var(--_color) 12%, transparent);
|
|
341
341
|
}
|
|
342
342
|
.eb-full-badge {
|
|
343
|
-
color: var(--dt-accent, #
|
|
344
|
-
background: color-mix(in srgb, var(--dt-accent, #
|
|
343
|
+
color: var(--dt-accent, #1d4fd7);
|
|
344
|
+
background: color-mix(in srgb, var(--dt-accent, #1d4fd7) 15%, transparent);
|
|
345
345
|
}
|
|
346
346
|
.eb-limited-badge {
|
|
347
347
|
color: var(--_color);
|
|
@@ -211,8 +211,8 @@ function onKeydown(e) {
|
|
|
211
211
|
max-height: calc(100vh - 16px);
|
|
212
212
|
display: flex;
|
|
213
213
|
flex-direction: column;
|
|
214
|
-
background: var(--dt-surface, #
|
|
215
|
-
color: var(--dt-text, #
|
|
214
|
+
background: var(--dt-surface, #f4f1ee);
|
|
215
|
+
color: var(--dt-text, #0f0f0f);
|
|
216
216
|
border: 1px solid var(--dt-border, #e2e2e2);
|
|
217
217
|
border-radius: var(--dt-radius, 8px);
|
|
218
218
|
box-shadow: var(--dt-shadow, 0 16px 48px rgba(0, 0, 0, 0.18));
|
|
@@ -252,8 +252,8 @@ function onKeydown(e) {
|
|
|
252
252
|
cursor: pointer;
|
|
253
253
|
}
|
|
254
254
|
.fp-close:hover {
|
|
255
|
-
background: var(--dt-hover, rgba(
|
|
256
|
-
color: var(--dt-text, #
|
|
255
|
+
background: var(--dt-hover, rgba(15, 15, 15, 0.06));
|
|
256
|
+
color: var(--dt-text, #0f0f0f);
|
|
257
257
|
}
|
|
258
258
|
.fp-body {
|
|
259
259
|
/* A flex child defaults to min-height:auto and never shrinks below its
|
|
@@ -74,7 +74,7 @@ const colorVar = $derived(color ? `--ni-color: ${color}` : "");
|
|
|
74
74
|
height: 0;
|
|
75
75
|
}
|
|
76
76
|
.ni-line-bar {
|
|
77
|
-
background: var(--ni-color, var(--dt-accent, #
|
|
77
|
+
background: var(--ni-color, var(--dt-accent, #1d4fd7));
|
|
78
78
|
}
|
|
79
79
|
.ni-line.vertical .ni-line-bar {
|
|
80
80
|
width: 2px;
|
|
@@ -92,8 +92,8 @@ const colorVar = $derived(color ? `--ni-color: ${color}` : "");
|
|
|
92
92
|
width: 10px;
|
|
93
93
|
height: 10px;
|
|
94
94
|
border-radius: 50%;
|
|
95
|
-
background: var(--ni-color, var(--dt-accent, #
|
|
96
|
-
box-shadow: 0 0 6px var(--ni-color, var(--dt-glow, rgba(
|
|
95
|
+
background: var(--ni-color, var(--dt-accent, #1d4fd7));
|
|
96
|
+
box-shadow: 0 0 6px var(--ni-color, var(--dt-glow, rgba(29, 79, 215, 0.25)));
|
|
97
97
|
}
|
|
98
98
|
.ni-dot.vertical .ni-dot-circle {
|
|
99
99
|
margin-left: -5px;
|
|
@@ -109,7 +109,7 @@ const colorVar = $derived(color ? `--ni-color: ${color}` : "");
|
|
|
109
109
|
font: 600 10px / 1 var(--dt-sans, system-ui, sans-serif);
|
|
110
110
|
font-variant-numeric: tabular-nums;
|
|
111
111
|
color: var(--dt-btn-text, #fff);
|
|
112
|
-
background: var(--ni-color, var(--dt-accent, #
|
|
112
|
+
background: var(--ni-color, var(--dt-accent, #1d4fd7));
|
|
113
113
|
padding: 3px 6px;
|
|
114
114
|
border-radius: 4px;
|
|
115
115
|
}
|
|
@@ -136,7 +136,7 @@ const colorVar = $derived(color ? `--ni-color: ${color}` : "");
|
|
|
136
136
|
letter-spacing: 0.08em;
|
|
137
137
|
text-transform: uppercase;
|
|
138
138
|
color: var(--dt-btn-text, #fff);
|
|
139
|
-
background: var(--ni-color, var(--dt-accent, #
|
|
139
|
+
background: var(--ni-color, var(--dt-accent, #1d4fd7));
|
|
140
140
|
padding: 2px 7px;
|
|
141
141
|
border-radius: 3px;
|
|
142
142
|
animation: ni-pulse 2s ease-in-out infinite;
|
|
@@ -51,7 +51,7 @@ const firstHour = $derived(hours[0] ?? 0);
|
|
|
51
51
|
top: 0;
|
|
52
52
|
bottom: 0;
|
|
53
53
|
width: 0;
|
|
54
|
-
border-left: 1px solid var(--dt-border, rgba(
|
|
54
|
+
border-left: 1px solid var(--dt-border, rgba(15, 15, 15, 0.08));
|
|
55
55
|
}
|
|
56
56
|
.tg-tick-half {
|
|
57
57
|
border-left-style: dashed;
|
|
@@ -63,7 +63,7 @@ const firstHour = $derived(hours[0] ?? 0);
|
|
|
63
63
|
left: 6px;
|
|
64
64
|
font: 400 9px / 1 var(--dt-sans, system-ui, sans-serif);
|
|
65
65
|
font-variant-numeric: tabular-nums;
|
|
66
|
-
color: var(--dt-text-3, rgba(
|
|
66
|
+
color: var(--dt-text-3, rgba(15, 15, 15, 0.38));
|
|
67
67
|
white-space: nowrap;
|
|
68
68
|
}
|
|
69
69
|
|
|
@@ -81,11 +81,11 @@ const firstHour = $derived(hours[0] ?? 0);
|
|
|
81
81
|
align-items: flex-start;
|
|
82
82
|
justify-content: flex-end;
|
|
83
83
|
padding: 2px 8px 0 0;
|
|
84
|
-
border-top: 1px solid var(--dt-border, rgba(
|
|
84
|
+
border-top: 1px solid var(--dt-border, rgba(15, 15, 15, 0.08));
|
|
85
85
|
}
|
|
86
86
|
.tg-v .tg-label {
|
|
87
87
|
font: 400 9px / 1 var(--dt-sans, system-ui, sans-serif);
|
|
88
88
|
font-variant-numeric: tabular-nums;
|
|
89
|
-
color: var(--dt-text-3, rgba(
|
|
89
|
+
color: var(--dt-text-3, rgba(15, 15, 15, 0.38));
|
|
90
90
|
}
|
|
91
91
|
</style>
|
package/dist/theme/auto.d.ts
CHANGED
|
@@ -14,6 +14,11 @@
|
|
|
14
14
|
*
|
|
15
15
|
* The Calendar component calls this automatically when theme is `auto` (empty string).
|
|
16
16
|
*/
|
|
17
|
+
/**
|
|
18
|
+
* Text colour for an accent fill (all-day band, now plate): white when it
|
|
19
|
+
* reaches 4.5:1 on the accent, else whichever of white / dark ink contrasts more.
|
|
20
|
+
*/
|
|
21
|
+
export declare function accentTextFor(accent: [number, number, number]): '#ffffff' | '#0f0f0f';
|
|
17
22
|
/** Options for fine-tuning auto-detection behavior. */
|
|
18
23
|
export interface AutoThemeOptions {
|
|
19
24
|
/**
|