@0001-labs/design-system-1 0.3.0-alpha.21 → 0.3.0-alpha.22
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/DS1/0-face/calendar.ts +23 -0
- package/DS1/1-root/cjk.css +1 -1
- package/DS1/1-root/fonts.css +1 -1
- package/DS1/1-root/one.css +1 -1
- package/DS1/1-root/one.semantic.css +1 -1
- package/DS1/3-unit/ds-calendar.ts +19 -1
- package/DS1/3-unit/styles/ds-calendar.css +25 -0
- package/dist/0-face/calendar.d.ts +11 -0
- package/dist/0-face/calendar.d.ts.map +1 -1
- package/dist/0-face/calendar.js +19 -0
- package/dist/3-unit/ds-calendar.d.ts +17 -0
- package/dist/3-unit/ds-calendar.d.ts.map +1 -1
- package/dist/3-unit/ds-calendar.js +16 -2
- package/dist/design-system-1.bundle.js +39 -2
- package/dist/design-system-1.bundle.js.map +1 -1
- package/dist/design-system-1.bundle.min.js +651 -631
- package/dist/design-system-1.bundle.min.js.map +1 -1
- package/package.json +1 -1
package/DS1/0-face/calendar.ts
CHANGED
|
@@ -173,8 +173,31 @@ export type CalendarEvent = {
|
|
|
173
173
|
time?: string;
|
|
174
174
|
/** A colour token or value for the event's fill (`var(--ds-zenith-blue)`). */
|
|
175
175
|
color?: string;
|
|
176
|
+
/** How much it counts for in a calendar's heat (commits, purchases, hours); 1 when left out. */
|
|
177
|
+
count?: number;
|
|
176
178
|
};
|
|
177
179
|
|
|
180
|
+
/** A day's heat: 1 (a little) to 4 (the most). */
|
|
181
|
+
export type HeatLevel = 1 | 2 | 3 | 4;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* How strongly each day is lit, as a contribution graph lights it: the
|
|
185
|
+
* amounts of its events added up, in four steps of the busiest day (or of
|
|
186
|
+
* `max`, for a scale that stays put from month to month). A day with nothing
|
|
187
|
+
* has no level.
|
|
188
|
+
*/
|
|
189
|
+
export function heatLevels(byDay: ReadonlyMap<Day, readonly CalendarEvent[]>, max?: number): Map<Day, HeatLevel> {
|
|
190
|
+
const amounts = new Map<Day, number>();
|
|
191
|
+
for (const [day, events] of byDay) {
|
|
192
|
+
const amount = events.reduce((sum, event) => sum + (typeof event.count === "number" && Number.isFinite(event.count) ? Math.max(0, event.count) : 1), 0);
|
|
193
|
+
if (amount > 0) amounts.set(day, amount);
|
|
194
|
+
}
|
|
195
|
+
const top = typeof max === "number" && Number.isFinite(max) && max > 0 ? max : Math.max(0, ...amounts.values());
|
|
196
|
+
const levels = new Map<Day, HeatLevel>();
|
|
197
|
+
for (const [day, amount] of amounts) levels.set(day, Math.min(4, Math.max(1, Math.ceil((amount / top) * 4))) as HeatLevel);
|
|
198
|
+
return levels;
|
|
199
|
+
}
|
|
200
|
+
|
|
178
201
|
/** The events that touch each day between `from` and `to`, in order: longest first, then by time. */
|
|
179
202
|
export function eventsByDay(events: readonly CalendarEvent[], from: Day, to: Day): Map<Day, CalendarEvent[]> {
|
|
180
203
|
const days = new Map<Day, CalendarEvent[]>();
|
package/DS1/1-root/cjk.css
CHANGED
package/DS1/1-root/fonts.css
CHANGED
package/DS1/1-root/one.css
CHANGED
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
dateNumber,
|
|
22
22
|
dayOf,
|
|
23
23
|
eventsByDay,
|
|
24
|
+
heatLevels,
|
|
24
25
|
isDay,
|
|
25
26
|
isoWeek,
|
|
26
27
|
monthTitle,
|
|
@@ -30,6 +31,7 @@ import {
|
|
|
30
31
|
weekdayNames,
|
|
31
32
|
type CalendarEvent,
|
|
32
33
|
type Day,
|
|
34
|
+
type HeatLevel,
|
|
33
35
|
} from "../0-face/calendar";
|
|
34
36
|
import { CalendarBase, readMonth, readRange, type CalendarChangeDetail } from "./calendar-base";
|
|
35
37
|
import "../2-core/ds-icon";
|
|
@@ -105,6 +107,12 @@ const openPickers = new Set<Calendar>();
|
|
|
105
107
|
* @prop {boolean} fixed - Always draw six weeks, so the month keeps its height.
|
|
106
108
|
* @prop {boolean} outsideDays - Draw the days of the months before and after
|
|
107
109
|
* in the title grey (`outside-days`); pressing one moves there.
|
|
110
|
+
* @prop {boolean} heat - Light each day by how much happens on it, as a
|
|
111
|
+
* contribution graph does: the events' `count`s added up (one each by
|
|
112
|
+
* default), in four steps of the busiest day shown.
|
|
113
|
+
* @prop {number} heatMax - The amount that lights a day fully (`heat-max`),
|
|
114
|
+
* for a scale that stays put from month to month; the busiest day shown
|
|
115
|
+
* by default.
|
|
108
116
|
* @prop {boolean} noHeader - Leave out the title and arrows (`no-header`).
|
|
109
117
|
* @prop {boolean} noToday - Leave out the Today button (`no-today`).
|
|
110
118
|
* @prop {string} min - The first day a person may choose.
|
|
@@ -153,6 +161,8 @@ export class Calendar extends CalendarBase {
|
|
|
153
161
|
outsideDays: { type: Boolean, attribute: "outside-days", reflect: true },
|
|
154
162
|
noHeader: { type: Boolean, attribute: "no-header", reflect: true },
|
|
155
163
|
noToday: { type: Boolean, attribute: "no-today", reflect: true },
|
|
164
|
+
heat: { type: Boolean, reflect: true },
|
|
165
|
+
heatMax: { type: Number, attribute: "heat-max" },
|
|
156
166
|
picker: { type: Boolean, reflect: true },
|
|
157
167
|
name: { type: String, reflect: true },
|
|
158
168
|
placeholder: { type: String },
|
|
@@ -175,6 +185,8 @@ export class Calendar extends CalendarBase {
|
|
|
175
185
|
declare outsideDays: boolean;
|
|
176
186
|
declare noHeader: boolean;
|
|
177
187
|
declare noToday: boolean;
|
|
188
|
+
declare heat: boolean;
|
|
189
|
+
declare heatMax: number | undefined;
|
|
178
190
|
declare picker: boolean;
|
|
179
191
|
declare name: string | undefined;
|
|
180
192
|
declare placeholder: string | undefined;
|
|
@@ -189,6 +201,7 @@ export class Calendar extends CalendarBase {
|
|
|
189
201
|
protected readonly weeksRun = "rows" as const;
|
|
190
202
|
|
|
191
203
|
private byDay = new Map<Day, CalendarEvent[]>();
|
|
204
|
+
private heatByDay = new Map<Day, HeatLevel>();
|
|
192
205
|
private readonly internals = typeof this.attachInternals === "function" ? this.attachInternals() : null;
|
|
193
206
|
/** The value the field started with, for a form's reset. */
|
|
194
207
|
private initial = "";
|
|
@@ -204,6 +217,7 @@ export class Calendar extends CalendarBase {
|
|
|
204
217
|
this.outsideDays = false;
|
|
205
218
|
this.noHeader = false;
|
|
206
219
|
this.noToday = false;
|
|
220
|
+
this.heat = false;
|
|
207
221
|
this.picker = false;
|
|
208
222
|
this.time = false;
|
|
209
223
|
this.required = false;
|
|
@@ -400,7 +414,8 @@ export class Calendar extends CalendarBase {
|
|
|
400
414
|
const unfolded = this.unfolded === day;
|
|
401
415
|
const shown = unfolded || events.length <= lines ? events : events.slice(0, Math.max(0, lines - 1));
|
|
402
416
|
const hidden = events.length - shown.length;
|
|
403
|
-
const
|
|
417
|
+
const heat = this.heatByDay.get(day);
|
|
418
|
+
const parts = ["day", isToday ? "today" : "", selected ? "selected" : "", heat ? "heat" : ""].filter(Boolean).join(" ");
|
|
404
419
|
return html`<div
|
|
405
420
|
role="gridcell"
|
|
406
421
|
class="day"
|
|
@@ -418,6 +433,7 @@ export class Calendar extends CalendarBase {
|
|
|
418
433
|
?data-last=${last}
|
|
419
434
|
?data-outside=${outside}
|
|
420
435
|
?data-busy=${events.length > 0}
|
|
436
|
+
data-heat=${heat ?? nothing}
|
|
421
437
|
?data-open=${unfolded}
|
|
422
438
|
>
|
|
423
439
|
<span class="date-line" aria-hidden="true">
|
|
@@ -444,6 +460,8 @@ export class Calendar extends CalendarBase {
|
|
|
444
460
|
const first = this.firstDay;
|
|
445
461
|
const weeks = monthWeeks(month, first, this.fixed);
|
|
446
462
|
this.byDay = eventsByDay(this.events ?? [], weeks[0][0], weeks.at(-1)![6]);
|
|
463
|
+
// Heat is measured over the days of the month shown, so the neighbours' days never set its scale.
|
|
464
|
+
this.heatByDay = this.heat ? heatLevels(new Map([...this.byDay].filter(([day]) => sameMonth(day, month))), this.heatMax) : new Map();
|
|
447
465
|
// A compact month names its days in a letter (one square) or two (wider); a full month in short.
|
|
448
466
|
const short = this.compact
|
|
449
467
|
? this.squaresPerDay < 2
|
|
@@ -25,6 +25,17 @@
|
|
|
25
25
|
--ds-calendar-band: color-mix(in srgb, var(--ds-calendar-selected) 16%, var(--ds-paper));
|
|
26
26
|
--ds-calendar-mark: calc(var(--ds-unit) * 0.9);
|
|
27
27
|
--ds-calendar-pad: calc(4px * var(--ds-sf, 1));
|
|
28
|
+
/* Heat, in four steps of the accent: its pastel, between, the colour, and
|
|
29
|
+
past it (deepened with the ink on light paper, the full colour on dark).
|
|
30
|
+
The words are the ink on every step but the two darkest on dark paper. */
|
|
31
|
+
--ds-calendar-heat-1: var(--one-apple-green-pastel, color-mix(in srgb, var(--ds-apple-green) 40%, var(--ds-paper)));
|
|
32
|
+
--ds-calendar-heat-3: var(--one-apple-green, var(--ds-apple-green));
|
|
33
|
+
--ds-calendar-heat-2: color-mix(in srgb, var(--ds-calendar-heat-1), var(--ds-calendar-heat-3));
|
|
34
|
+
--ds-calendar-heat-4: light-dark(color-mix(in srgb, var(--ds-apple-green) 60%, var(--ds-slate)), var(--ds-apple-green));
|
|
35
|
+
--ds-calendar-heat-ink-1: light-dark(var(--ds-slate), var(--ds-white));
|
|
36
|
+
--ds-calendar-heat-ink-2: light-dark(var(--ds-slate), var(--ds-white));
|
|
37
|
+
--ds-calendar-heat-ink-3: var(--ds-slate);
|
|
38
|
+
--ds-calendar-heat-ink-4: var(--ds-slate);
|
|
28
39
|
box-sizing: border-box;
|
|
29
40
|
display: inline-block;
|
|
30
41
|
vertical-align: top;
|
|
@@ -175,6 +186,20 @@
|
|
|
175
186
|
|
|
176
187
|
.day[aria-disabled="true"] .date { color: var(--ds-title-color); opacity: 0.5; }
|
|
177
188
|
|
|
189
|
+
/* Heat: the date's mark filled by its step, a picture's corners, inside the day's square; today and the selection draw over it. */
|
|
190
|
+
.day[data-heat]:not([data-today], [data-selected]) .date-line { align-items: center; padding-inline-end: calc(var(--ds-unit) * 0.05); }
|
|
191
|
+
.day[data-heat]:not([data-today], [data-selected]) .date {
|
|
192
|
+
min-width: var(--ds-calendar-mark);
|
|
193
|
+
height: var(--ds-calendar-mark);
|
|
194
|
+
border-radius: var(--ds-radius);
|
|
195
|
+
letter-spacing: 0;
|
|
196
|
+
}
|
|
197
|
+
.day[data-heat="1"]:not([data-today], [data-selected]) .date { background: var(--ds-calendar-heat-1); color: var(--ds-calendar-heat-ink-1); }
|
|
198
|
+
.day[data-heat="2"]:not([data-today], [data-selected]) .date { background: var(--ds-calendar-heat-2); color: var(--ds-calendar-heat-ink-2); }
|
|
199
|
+
.day[data-heat="3"]:not([data-today], [data-selected]) .date { background: var(--ds-calendar-heat-3); color: var(--ds-calendar-heat-ink-3); }
|
|
200
|
+
.day[data-heat="4"]:not([data-today], [data-selected]) .date { background: var(--ds-calendar-heat-4); color: var(--ds-calendar-heat-ink-4); }
|
|
201
|
+
:host([compact]) .day[data-heat]:not([data-today], [data-selected]) .date-line { padding: 0; }
|
|
202
|
+
|
|
178
203
|
/* Events: one square each, stacked edge to edge on the day's lines, drawn one pixel short. */
|
|
179
204
|
.events {
|
|
180
205
|
display: flex;
|
|
@@ -69,7 +69,18 @@ export type CalendarEvent = {
|
|
|
69
69
|
time?: string;
|
|
70
70
|
/** A colour token or value for the event's fill (`var(--ds-zenith-blue)`). */
|
|
71
71
|
color?: string;
|
|
72
|
+
/** How much it counts for in a calendar's heat (commits, purchases, hours); 1 when left out. */
|
|
73
|
+
count?: number;
|
|
72
74
|
};
|
|
75
|
+
/** A day's heat: 1 (a little) to 4 (the most). */
|
|
76
|
+
export type HeatLevel = 1 | 2 | 3 | 4;
|
|
77
|
+
/**
|
|
78
|
+
* How strongly each day is lit, as a contribution graph lights it: the
|
|
79
|
+
* amounts of its events added up, in four steps of the busiest day (or of
|
|
80
|
+
* `max`, for a scale that stays put from month to month). A day with nothing
|
|
81
|
+
* has no level.
|
|
82
|
+
*/
|
|
83
|
+
export declare function heatLevels(byDay: ReadonlyMap<Day, readonly CalendarEvent[]>, max?: number): Map<Day, HeatLevel>;
|
|
73
84
|
/** The events that touch each day between `from` and `to`, in order: longest first, then by time. */
|
|
74
85
|
export declare function eventsByDay(events: readonly CalendarEvent[], from: Day, to: Day): Map<Day, CalendarEvent[]>;
|
|
75
86
|
//# sourceMappingURL=calendar.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calendar.d.ts","sourceRoot":"","sources":["../../DS1/0-face/calendar.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"calendar.d.ts","sourceRoot":"","sources":["../../DS1/0-face/calendar.ts"],"names":[],"mappings":"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"}
|
package/dist/0-face/calendar.js
CHANGED
|
@@ -129,6 +129,25 @@ export function isoWeek(day) {
|
|
|
129
129
|
const firstThursday = addDays(january4, 3 - ((weekdayOf(january4) + 6) % 7));
|
|
130
130
|
return 1 + Math.round((noon(thursday) - noon(firstThursday)) / (7 * 864e5));
|
|
131
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* How strongly each day is lit, as a contribution graph lights it: the
|
|
134
|
+
* amounts of its events added up, in four steps of the busiest day (or of
|
|
135
|
+
* `max`, for a scale that stays put from month to month). A day with nothing
|
|
136
|
+
* has no level.
|
|
137
|
+
*/
|
|
138
|
+
export function heatLevels(byDay, max) {
|
|
139
|
+
const amounts = new Map();
|
|
140
|
+
for (const [day, events] of byDay) {
|
|
141
|
+
const amount = events.reduce((sum, event) => sum + (typeof event.count === "number" && Number.isFinite(event.count) ? Math.max(0, event.count) : 1), 0);
|
|
142
|
+
if (amount > 0)
|
|
143
|
+
amounts.set(day, amount);
|
|
144
|
+
}
|
|
145
|
+
const top = typeof max === "number" && Number.isFinite(max) && max > 0 ? max : Math.max(0, ...amounts.values());
|
|
146
|
+
const levels = new Map();
|
|
147
|
+
for (const [day, amount] of amounts)
|
|
148
|
+
levels.set(day, Math.min(4, Math.max(1, Math.ceil((amount / top) * 4))));
|
|
149
|
+
return levels;
|
|
150
|
+
}
|
|
132
151
|
/** The events that touch each day between `from` and `to`, in order: longest first, then by time. */
|
|
133
152
|
export function eventsByDay(events, from, to) {
|
|
134
153
|
const days = new Map();
|
|
@@ -44,6 +44,12 @@ export declare function parseTypedDay(text: string): Day | null;
|
|
|
44
44
|
* @prop {boolean} fixed - Always draw six weeks, so the month keeps its height.
|
|
45
45
|
* @prop {boolean} outsideDays - Draw the days of the months before and after
|
|
46
46
|
* in the title grey (`outside-days`); pressing one moves there.
|
|
47
|
+
* @prop {boolean} heat - Light each day by how much happens on it, as a
|
|
48
|
+
* contribution graph does: the events' `count`s added up (one each by
|
|
49
|
+
* default), in four steps of the busiest day shown.
|
|
50
|
+
* @prop {number} heatMax - The amount that lights a day fully (`heat-max`),
|
|
51
|
+
* for a scale that stays put from month to month; the busiest day shown
|
|
52
|
+
* by default.
|
|
47
53
|
* @prop {boolean} noHeader - Leave out the title and arrows (`no-header`).
|
|
48
54
|
* @prop {boolean} noToday - Leave out the Today button (`no-today`).
|
|
49
55
|
* @prop {string} min - The first day a person may choose.
|
|
@@ -120,6 +126,14 @@ export declare class Calendar extends CalendarBase {
|
|
|
120
126
|
attribute: string;
|
|
121
127
|
reflect: boolean;
|
|
122
128
|
};
|
|
129
|
+
heat: {
|
|
130
|
+
type: BooleanConstructor;
|
|
131
|
+
reflect: boolean;
|
|
132
|
+
};
|
|
133
|
+
heatMax: {
|
|
134
|
+
type: NumberConstructor;
|
|
135
|
+
attribute: string;
|
|
136
|
+
};
|
|
123
137
|
picker: {
|
|
124
138
|
type: BooleanConstructor;
|
|
125
139
|
reflect: boolean;
|
|
@@ -204,6 +218,8 @@ export declare class Calendar extends CalendarBase {
|
|
|
204
218
|
outsideDays: boolean;
|
|
205
219
|
noHeader: boolean;
|
|
206
220
|
noToday: boolean;
|
|
221
|
+
heat: boolean;
|
|
222
|
+
heatMax: number | undefined;
|
|
207
223
|
picker: boolean;
|
|
208
224
|
name: string | undefined;
|
|
209
225
|
placeholder: string | undefined;
|
|
@@ -216,6 +232,7 @@ export declare class Calendar extends CalendarBase {
|
|
|
216
232
|
unfolded: Day | undefined;
|
|
217
233
|
protected readonly weeksRun: "rows";
|
|
218
234
|
private byDay;
|
|
235
|
+
private heatByDay;
|
|
219
236
|
private readonly internals;
|
|
220
237
|
/** The value the field started with, for a form's reset. */
|
|
221
238
|
private initial;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ds-calendar.d.ts","sourceRoot":"","sources":["../../DS1/3-unit/ds-calendar.ts"],"names":[],"mappings":"AAcA,OAAO,EAA4B,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAGpE,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,
|
|
1
|
+
{"version":3,"file":"ds-calendar.d.ts","sourceRoot":"","sources":["../../DS1/3-unit/ds-calendar.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,7 +15,7 @@ import { html, nothing, unsafeCSS } from "lit";
|
|
|
15
15
|
import { define } from "../0-face/define";
|
|
16
16
|
import { getText } from "../0-face/i18n";
|
|
17
17
|
import { dateFormatter } from "../0-face/format";
|
|
18
|
-
import { addMonths, dateNumber, dayOf, eventsByDay, isDay, isoWeek, monthTitle, monthWeeks, sameMonth, startOfMonth, weekdayNames, } from "../0-face/calendar";
|
|
18
|
+
import { addMonths, dateNumber, dayOf, eventsByDay, heatLevels, isDay, isoWeek, monthTitle, monthWeeks, sameMonth, startOfMonth, weekdayNames, } from "../0-face/calendar";
|
|
19
19
|
import { CalendarBase, readMonth, readRange } from "./calendar-base";
|
|
20
20
|
import "../2-core/ds-icon";
|
|
21
21
|
import metrics from "../1-root/component-metrics.css?inline";
|
|
@@ -79,6 +79,12 @@ const openPickers = new Set();
|
|
|
79
79
|
* @prop {boolean} fixed - Always draw six weeks, so the month keeps its height.
|
|
80
80
|
* @prop {boolean} outsideDays - Draw the days of the months before and after
|
|
81
81
|
* in the title grey (`outside-days`); pressing one moves there.
|
|
82
|
+
* @prop {boolean} heat - Light each day by how much happens on it, as a
|
|
83
|
+
* contribution graph does: the events' `count`s added up (one each by
|
|
84
|
+
* default), in four steps of the busiest day shown.
|
|
85
|
+
* @prop {number} heatMax - The amount that lights a day fully (`heat-max`),
|
|
86
|
+
* for a scale that stays put from month to month; the busiest day shown
|
|
87
|
+
* by default.
|
|
82
88
|
* @prop {boolean} noHeader - Leave out the title and arrows (`no-header`).
|
|
83
89
|
* @prop {boolean} noToday - Leave out the Today button (`no-today`).
|
|
84
90
|
* @prop {string} min - The first day a person may choose.
|
|
@@ -118,6 +124,7 @@ export class Calendar extends CalendarBase {
|
|
|
118
124
|
super();
|
|
119
125
|
this.weeksRun = "rows";
|
|
120
126
|
this.byDay = new Map();
|
|
127
|
+
this.heatByDay = new Map();
|
|
121
128
|
this.internals = typeof this.attachInternals === "function" ? this.attachInternals() : null;
|
|
122
129
|
/** The value the field started with, for a form's reset. */
|
|
123
130
|
this.initial = "";
|
|
@@ -280,6 +287,7 @@ export class Calendar extends CalendarBase {
|
|
|
280
287
|
this.outsideDays = false;
|
|
281
288
|
this.noHeader = false;
|
|
282
289
|
this.noToday = false;
|
|
290
|
+
this.heat = false;
|
|
283
291
|
this.picker = false;
|
|
284
292
|
this.time = false;
|
|
285
293
|
this.required = false;
|
|
@@ -416,7 +424,8 @@ export class Calendar extends CalendarBase {
|
|
|
416
424
|
const unfolded = this.unfolded === day;
|
|
417
425
|
const shown = unfolded || events.length <= lines ? events : events.slice(0, Math.max(0, lines - 1));
|
|
418
426
|
const hidden = events.length - shown.length;
|
|
419
|
-
const
|
|
427
|
+
const heat = this.heatByDay.get(day);
|
|
428
|
+
const parts = ["day", isToday ? "today" : "", selected ? "selected" : "", heat ? "heat" : ""].filter(Boolean).join(" ");
|
|
420
429
|
return html `<div
|
|
421
430
|
role="gridcell"
|
|
422
431
|
class="day"
|
|
@@ -434,6 +443,7 @@ export class Calendar extends CalendarBase {
|
|
|
434
443
|
?data-last=${last}
|
|
435
444
|
?data-outside=${outside}
|
|
436
445
|
?data-busy=${events.length > 0}
|
|
446
|
+
data-heat=${heat ?? nothing}
|
|
437
447
|
?data-open=${unfolded}
|
|
438
448
|
>
|
|
439
449
|
<span class="date-line" aria-hidden="true">
|
|
@@ -460,6 +470,8 @@ export class Calendar extends CalendarBase {
|
|
|
460
470
|
const first = this.firstDay;
|
|
461
471
|
const weeks = monthWeeks(month, first, this.fixed);
|
|
462
472
|
this.byDay = eventsByDay(this.events ?? [], weeks[0][0], weeks.at(-1)[6]);
|
|
473
|
+
// Heat is measured over the days of the month shown, so the neighbours' days never set its scale.
|
|
474
|
+
this.heatByDay = this.heat ? heatLevels(new Map([...this.byDay].filter(([day]) => sameMonth(day, month))), this.heatMax) : new Map();
|
|
463
475
|
// A compact month names its days in a letter (one square) or two (wider); a full month in short.
|
|
464
476
|
const short = this.compact
|
|
465
477
|
? this.squaresPerDay < 2
|
|
@@ -730,6 +742,8 @@ Calendar.properties = {
|
|
|
730
742
|
outsideDays: { type: Boolean, attribute: "outside-days", reflect: true },
|
|
731
743
|
noHeader: { type: Boolean, attribute: "no-header", reflect: true },
|
|
732
744
|
noToday: { type: Boolean, attribute: "no-today", reflect: true },
|
|
745
|
+
heat: { type: Boolean, reflect: true },
|
|
746
|
+
heatMax: { type: Number, attribute: "heat-max" },
|
|
733
747
|
picker: { type: Boolean, reflect: true },
|
|
734
748
|
name: { type: String, reflect: true },
|
|
735
749
|
placeholder: { type: String },
|
|
@@ -10695,6 +10695,23 @@ function isoWeek(day) {
|
|
|
10695
10695
|
const firstThursday = addDays(january4, 3 - (weekdayOf(january4) + 6) % 7);
|
|
10696
10696
|
return 1 + Math.round((noon(thursday) - noon(firstThursday)) / 6048e5);
|
|
10697
10697
|
}
|
|
10698
|
+
/**
|
|
10699
|
+
* How strongly each day is lit, as a contribution graph lights it: the
|
|
10700
|
+
* amounts of its events added up, in four steps of the busiest day (or of
|
|
10701
|
+
* `max`, for a scale that stays put from month to month). A day with nothing
|
|
10702
|
+
* has no level.
|
|
10703
|
+
*/
|
|
10704
|
+
function heatLevels(byDay, max) {
|
|
10705
|
+
const amounts = /* @__PURE__ */ new Map();
|
|
10706
|
+
for (const [day, events] of byDay) {
|
|
10707
|
+
const amount = events.reduce((sum, event) => sum + (typeof event.count === "number" && Number.isFinite(event.count) ? Math.max(0, event.count) : 1), 0);
|
|
10708
|
+
if (amount > 0) amounts.set(day, amount);
|
|
10709
|
+
}
|
|
10710
|
+
const top = typeof max === "number" && Number.isFinite(max) && max > 0 ? max : Math.max(0, ...amounts.values());
|
|
10711
|
+
const levels = /* @__PURE__ */ new Map();
|
|
10712
|
+
for (const [day, amount] of amounts) levels.set(day, Math.min(4, Math.max(1, Math.ceil(amount / top * 4))));
|
|
10713
|
+
return levels;
|
|
10714
|
+
}
|
|
10698
10715
|
/** The events that touch each day between `from` and `to`, in order: longest first, then by time. */
|
|
10699
10716
|
function eventsByDay(events, from, to) {
|
|
10700
10717
|
const days = /* @__PURE__ */ new Map();
|
|
@@ -10928,7 +10945,7 @@ _CalendarBase.properties = {
|
|
|
10928
10945
|
};
|
|
10929
10946
|
//#endregion
|
|
10930
10947
|
//#region DS1/3-unit/styles/ds-calendar.css?inline
|
|
10931
|
-
var ds_calendar_default = "/* ds-calendar.css\n * A month on whole squares. A day is --ds-calendar-day-squares wide (four,\n * one when compact) and, beside its date's square, holds --ds-calendar-lines\n * one-square lines of events and one square to spare. Every line of words\n * stands on the lower sixteen of its square. The boxes are hairlines centred\n * on the grid lines; today is a red disc nine tenths of a square across.\n *\n * A picker is the select's face: one control high at the foot of its square,\n * ten squares wide by default, the calendar icon at its start and the down\n * arrow at its end. Its month opens on the menu's frame, half a square from\n * the field: a 1px line, half a square inside it, no shadow, so eight squares\n * wide. Inside, on whole squares: the first and last day to type (each with\n * its time below when times are on), one square spare, the compact month one\n * square a day, then Include time and Clear, each one square, set off by\n * one-square separators with a line through them. */\n\n:host {\n --ds-calendar-day: calc(var(--ds-unit) * var(--ds-calendar-day-squares, 4));\n --ds-calendar-day-height: calc(var(--ds-unit) * (var(--ds-calendar-lines, 2) + 2));\n --ds-calendar-line: 1px solid var(--ds-border-color);\n --ds-calendar-today: var(--ds-red-for-blood);\n --ds-calendar-today-ink: var(--ds-white, #fff);\n --ds-calendar-selected: var(--ds-sharp-blue);\n --ds-calendar-selected-ink: var(--ds-white, #fff);\n --ds-calendar-band: color-mix(in srgb, var(--ds-calendar-selected) 16%, var(--ds-paper));\n --ds-calendar-mark: calc(var(--ds-unit) * 0.9);\n --ds-calendar-pad: calc(4px * var(--ds-sf, 1));\n box-sizing: border-box;\n display: inline-block;\n vertical-align: top;\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-type-lineheight-default);\n letter-spacing: var(--ds-type-letterspacing-default);\n}\n:host([hidden]) { display: none !important; }\n/* A compact day is square: one square, or two where the month has room. Its marks grow with it. */\n:host([compact]) {\n --ds-calendar-day-height: var(--ds-calendar-day);\n --ds-calendar-mark: calc(var(--ds-unit) * (var(--ds-calendar-day-squares, 1) * 0.75 + 0.15));\n}\n\n.calendar { width: calc(7 * var(--ds-calendar-day)); }\n\n/* The title and the arrows: one square, one square above the days (none when compact). */\n.header {\n box-sizing: border-box;\n display: flex;\n align-items: flex-end;\n gap: var(--ds-calendar-pad);\n height: var(--ds-unit);\n margin-block-end: var(--ds-unit);\n}\n:host([compact]) .header { margin-block-end: 0; }\n.title {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n font-family: var(--ds-typeface-medium, var(--ds-typeface-regular));\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.controls {\n display: flex;\n flex: 0 0 auto;\n align-items: flex-end;\n gap: 0;\n}\n/* Each arrow is a chevron on its own square, one control high at the square's foot,\n * in the title grey; the pointer fills it with the system's corners and inks it. */\n.nav {\n flex: 0 0 auto;\n width: var(--ds-unit);\n height: var(--ds-control-height);\n border-radius: var(--ds-radius);\n color: var(--ds-title-color);\n}\n.nav:hover:not(:disabled) { background: var(--ds-fill); color: var(--ds-text-color); }\n:host(:dir(rtl)) .nav > ds-icon { transform: scaleX(-1); }\n\n.grid { outline: none; }\n.weekdays,\n.week {\n display: grid;\n grid-template-columns: repeat(7, var(--ds-calendar-day));\n}\n\n/* The weekday names: a block line in the title grey, at the start of a wide day, centred on a compact one. */\n.weekday {\n box-sizing: border-box;\n height: var(--ds-unit);\n padding: calc(4px * var(--ds-sf, 1)) var(--ds-calendar-pad) 0;\n overflow: hidden;\n color: var(--ds-title-color);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n:host([compact]) .weekday { padding-inline: 0; text-align: center; }\n\n/* A day's box: hairlines on the grid lines, top and start; the last column\n * and the last week close it at the end and the foot. */\n.day {\n position: relative;\n box-sizing: border-box;\n min-width: 0;\n height: var(--ds-calendar-day-height);\n outline: none;\n}\n.day::after {\n position: absolute;\n inset: -0.5px;\n border-block-start: var(--ds-calendar-line);\n border-inline-start: var(--ds-calendar-line);\n content: \"\";\n pointer-events: none;\n}\n.day:nth-child(7)::after { border-inline-end: var(--ds-calendar-line); }\n.week:last-child .day::after { border-block-end: var(--ds-calendar-line); }\n:host([compact]) .day::after { content: none; }\n\n.day[data-day] { cursor: default; }\n:host([selectable]) .day[data-day]:not([aria-disabled=\"true\"]) { cursor: pointer; }\n:host([selectable]:not([compact])) .day[data-day]:not([aria-disabled=\"true\"]):hover { background: var(--ds-row-fill-hover, var(--ds-fill)); }\n.day:focus-visible { outline: 2px solid var(--ds-focus-ring); outline-offset: -2px; }\n:host([compact]) .day:focus-visible { outline: none; }\n:host([compact]) .day:focus-visible .date { outline: 2px solid var(--ds-focus-ring); outline-offset: -1px; }\n\n/* The date: on the first square, at the end of a wide day, in the title grey. */\n.date-line {\n box-sizing: border-box;\n display: flex;\n align-items: flex-end;\n justify-content: flex-end;\n gap: var(--ds-calendar-pad);\n height: var(--ds-unit);\n padding-inline: var(--ds-calendar-pad);\n}\n.date {\n color: var(--ds-title-color);\n font-variant-numeric: tabular-nums;\n}\n.week-number {\n margin-inline-end: auto;\n color: var(--ds-title-color);\n font-family: var(--ds-typeface-compressed);\n}\n\n/* A compact day: the date centred in its square, in the ink; with events,\n * the empty days fall back to the title grey and the busy ones keep the ink. */\n:host([compact]) .date-line { justify-content: center; padding: 0; }\n:host([compact]) .date { color: var(--ds-text-color); }\n:host([compact][data-events]) .day:not([data-busy]) .date { color: var(--ds-title-color); }\n:host([compact][selectable]) .day[data-day]:not([aria-disabled=\"true\"], [data-today], [data-selected]):hover .date { background: var(--ds-fill); }\n\n/* Today and the selected day: a disc nine tenths of a square, centred on the date's square. */\n.day:is([data-today], [data-selected]) .date-line { align-items: center; padding-inline-end: calc(var(--ds-unit) * 0.05); }\n:host([compact]) .day:is([data-today], [data-selected]) .date-line { padding: 0; }\n.date {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: var(--ds-calendar-mark);\n height: var(--ds-calendar-mark);\n border-radius: 999px;\n}\n.day:not([data-today], [data-selected]) .date { min-width: 0; height: auto; }\n:host([compact]) .day .date { min-width: var(--ds-calendar-mark); height: var(--ds-calendar-mark); }\n.day[data-today] .date { background: var(--ds-calendar-today); color: var(--ds-calendar-today-ink); letter-spacing: 0; }\n/* The selected day, and each end of a range: a square with the system's corners in the selection's blue. */\n.day[data-selected] .date { border-radius: var(--ds-radius); background: var(--ds-calendar-selected); color: var(--ds-calendar-selected-ink); letter-spacing: 0; }\n\n.day[aria-disabled=\"true\"] .date { color: var(--ds-title-color); opacity: 0.5; }\n\n/* Events: one square each, stacked edge to edge on the day's lines, drawn one pixel short. */\n.events {\n display: flex;\n flex-direction: column;\n}\n.event,\n.more {\n box-sizing: border-box;\n display: flex;\n align-items: flex-end;\n gap: var(--ds-calendar-pad);\n height: calc(var(--ds-unit) - 1px);\n margin: 0.5px;\n padding-inline: var(--ds-calendar-pad);\n overflow: hidden;\n white-space: nowrap;\n}\n.event {\n background: var(--ds-calendar-event-fill, var(--ds-fill));\n color: var(--ds-calendar-event-ink, var(--ds-text-color));\n cursor: pointer;\n}\n.event .name { min-width: 0; overflow: hidden; text-overflow: ellipsis; }\n.event .time { flex: 0 0 auto; opacity: 0.6; font-variant-numeric: tabular-nums; }\n.more { color: var(--ds-title-color); cursor: pointer; }\n.more:hover { color: var(--ds-text-color); }\n\n/* A day whose hidden events are unfolded lays them over the days below. */\n.day[data-open] { z-index: 1; }\n.day[data-open] .events {\n position: absolute;\n inset-block-start: var(--ds-unit);\n inset-inline: 0;\n background: var(--ds-paper);\n box-shadow: 0 0 0 1px var(--ds-border-color);\n}\n\n@media (prefers-reduced-motion: no-preference) {\n .event, .more { transition: opacity 120ms ease; }\n}\n\n/* A compact day's date stands in the middle of its square once the square is two or more wide. */\n:host([compact][data-roomy]) .date-line { align-items: center; height: var(--ds-calendar-day-height); }\n\n/* The days of the months before and after, in the title grey. */\n.day[data-outside] .date { color: var(--ds-title-color); }\n:host([compact]) .day[data-outside] .date { color: var(--ds-title-color); }\n\n/* A range: the days between its ends on a band of the selection's blue; the band runs into each end's square. */\n.day[data-inside] { background: var(--ds-calendar-band); }\n:host(:not([compact])) .day:is([data-first], [data-last]) { background: var(--ds-calendar-band); }\n:host([compact]) .day[data-first] { background: linear-gradient(to right, transparent 50%, var(--ds-calendar-band) 50%); }\n:host([compact]) .day[data-last] { background: linear-gradient(to left, transparent 50%, var(--ds-calendar-band) 50%); }\n:host([compact]:dir(rtl)) .day[data-first] { background: linear-gradient(to left, transparent 50%, var(--ds-calendar-band) 50%); }\n:host([compact]:dir(rtl)) .day[data-last] { background: linear-gradient(to right, transparent 50%, var(--ds-calendar-band) 50%); }\n:host([compact][selectable]) .day[data-inside]:hover .date { background: transparent; }\n\n/* Today, as words in the title grey beside the arrows. */\n.today-button {\n height: var(--ds-control-height);\n padding-inline: calc(4px * var(--ds-sf, 1));\n border: 0;\n background: transparent;\n color: var(--ds-title-color);\n}\n.today-button:hover { background: var(--ds-fill); color: var(--ds-text-color); }\n\n/* In a compact month the pointer's day and the chosen day take squares with the system's corners; today keeps its disc. */\n:host([compact]) .date { border-radius: var(--ds-radius); }\n:host([compact]) .day[data-today]:not([data-selected]) .date { border-radius: 999px; }\n\n/* The picker: a field that opens the small month. */\n:host([picker]) {\n --ds-calendar-picker-width: calc(10 * var(--ds-unit));\n display: inline-flex;\n align-items: flex-end;\n vertical-align: bottom;\n height: var(--ds-unit);\n}\n\n.trigger {\n display: inline-flex;\n align-items: flex-end;\n gap: calc(4px * var(--ds-sf, 1));\n width: var(--ds-calendar-picker-width);\n padding-inline: 0 calc(4px * var(--ds-sf, 1));\n text-align: start;\n cursor: pointer;\n}\n.trigger:disabled { cursor: default; }\n.trigger .icon,\n.trigger .arrow { flex: 0 0 auto; }\n.trigger .text {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.trigger[data-empty] .text { color: var(--ds-title-color); }\n.trigger[aria-expanded=\"true\"] .arrow { transform: rotate(180deg); }\n\n/* The month's panel, on the menu's frame. */\n.popover {\n position: fixed;\n inset: auto;\n box-sizing: border-box;\n margin: 0;\n padding: calc(var(--ds-unit) / 2 - 1px);\n border: 1px solid var(--ds-border-color);\n border-radius: var(--ds-radius-card);\n background: var(--ds-paper);\n color: var(--ds-text-color);\n box-shadow: none;\n overflow: visible;\n}\n.popover:not(:popover-open) { display: none; }\n\n/* The days to type: a row of one square for each end, its time on the row below; one square spare after. */\n.fields { margin-block-end: var(--ds-unit); }\n.field-row {\n display: flex;\n align-items: flex-end;\n gap: calc(var(--ds-unit) / 2);\n height: var(--ds-unit);\n}\n.field { flex: 1 1 auto; min-width: 0; }\n.clock { flex: 1 1 auto; min-width: 0; }\n.fields, .options { width: calc(7 * var(--ds-unit)); }\n\n/* Include time and Clear, each one square, the words on the sixteen. */\n.option {\n box-sizing: border-box;\n display: flex;\n align-items: flex-end;\n justify-content: space-between;\n gap: var(--ds-unit);\n width: 100%;\n height: var(--ds-unit);\n margin: 0;\n padding: 0 calc(4px * var(--ds-sf, 1));\n border: 0;\n border-radius: var(--ds-radius);\n background: transparent;\n color: var(--ds-text-color);\n font: inherit;\n letter-spacing: inherit;\n text-align: start;\n cursor: pointer;\n}\n.option:hover:not(:disabled) { background: var(--ds-row-fill-hover, var(--ds-fill)); }\n.option:focus-visible { outline: 2px solid var(--ds-focus-ring); outline-offset: -2px; }\n.option:disabled { color: var(--ds-title-color); cursor: default; }\n.option .ds-switch { flex: 0 0 auto; }\n\n/* A separator: one square with a 1px line through its middle. */\n.separator {\n position: relative;\n height: var(--ds-unit);\n}\n.separator::after {\n position: absolute;\n inset-inline: 0;\n top: calc(50% - 0.5px);\n height: 1px;\n background: var(--ds-border-color);\n content: \"\";\n}\n\n@media (prefers-reduced-motion: no-preference) {\n .popover:popover-open {\n animation: ds-calendar-picker-in 140ms cubic-bezier(0.22, 1, 0.36, 1);\n }\n .trigger .arrow { transition: transform 140ms ease; }\n}\n@keyframes ds-calendar-picker-in {\n from { opacity: 0; transform: translateY(calc(-4px * var(--ds-sf, 1))); }\n to { opacity: 1; transform: none; }\n}\n";
|
|
10948
|
+
var ds_calendar_default = "/* ds-calendar.css\n * A month on whole squares. A day is --ds-calendar-day-squares wide (four,\n * one when compact) and, beside its date's square, holds --ds-calendar-lines\n * one-square lines of events and one square to spare. Every line of words\n * stands on the lower sixteen of its square. The boxes are hairlines centred\n * on the grid lines; today is a red disc nine tenths of a square across.\n *\n * A picker is the select's face: one control high at the foot of its square,\n * ten squares wide by default, the calendar icon at its start and the down\n * arrow at its end. Its month opens on the menu's frame, half a square from\n * the field: a 1px line, half a square inside it, no shadow, so eight squares\n * wide. Inside, on whole squares: the first and last day to type (each with\n * its time below when times are on), one square spare, the compact month one\n * square a day, then Include time and Clear, each one square, set off by\n * one-square separators with a line through them. */\n\n:host {\n --ds-calendar-day: calc(var(--ds-unit) * var(--ds-calendar-day-squares, 4));\n --ds-calendar-day-height: calc(var(--ds-unit) * (var(--ds-calendar-lines, 2) + 2));\n --ds-calendar-line: 1px solid var(--ds-border-color);\n --ds-calendar-today: var(--ds-red-for-blood);\n --ds-calendar-today-ink: var(--ds-white, #fff);\n --ds-calendar-selected: var(--ds-sharp-blue);\n --ds-calendar-selected-ink: var(--ds-white, #fff);\n --ds-calendar-band: color-mix(in srgb, var(--ds-calendar-selected) 16%, var(--ds-paper));\n --ds-calendar-mark: calc(var(--ds-unit) * 0.9);\n --ds-calendar-pad: calc(4px * var(--ds-sf, 1));\n /* Heat, in four steps of the accent: its pastel, between, the colour, and\n past it (deepened with the ink on light paper, the full colour on dark).\n The words are the ink on every step but the two darkest on dark paper. */\n --ds-calendar-heat-1: var(--one-apple-green-pastel, color-mix(in srgb, var(--ds-apple-green) 40%, var(--ds-paper)));\n --ds-calendar-heat-3: var(--one-apple-green, var(--ds-apple-green));\n --ds-calendar-heat-2: color-mix(in srgb, var(--ds-calendar-heat-1), var(--ds-calendar-heat-3));\n --ds-calendar-heat-4: light-dark(color-mix(in srgb, var(--ds-apple-green) 60%, var(--ds-slate)), var(--ds-apple-green));\n --ds-calendar-heat-ink-1: light-dark(var(--ds-slate), var(--ds-white));\n --ds-calendar-heat-ink-2: light-dark(var(--ds-slate), var(--ds-white));\n --ds-calendar-heat-ink-3: var(--ds-slate);\n --ds-calendar-heat-ink-4: var(--ds-slate);\n box-sizing: border-box;\n display: inline-block;\n vertical-align: top;\n color: var(--ds-text-color);\n font-family: var(--ds-typeface-regular);\n font-feature-settings: var(--ds-font-features);\n font-size: var(--ds-type-size-default);\n font-weight: var(--ds-type-weight-default);\n line-height: var(--ds-type-lineheight-default);\n letter-spacing: var(--ds-type-letterspacing-default);\n}\n:host([hidden]) { display: none !important; }\n/* A compact day is square: one square, or two where the month has room. Its marks grow with it. */\n:host([compact]) {\n --ds-calendar-day-height: var(--ds-calendar-day);\n --ds-calendar-mark: calc(var(--ds-unit) * (var(--ds-calendar-day-squares, 1) * 0.75 + 0.15));\n}\n\n.calendar { width: calc(7 * var(--ds-calendar-day)); }\n\n/* The title and the arrows: one square, one square above the days (none when compact). */\n.header {\n box-sizing: border-box;\n display: flex;\n align-items: flex-end;\n gap: var(--ds-calendar-pad);\n height: var(--ds-unit);\n margin-block-end: var(--ds-unit);\n}\n:host([compact]) .header { margin-block-end: 0; }\n.title {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n font-family: var(--ds-typeface-medium, var(--ds-typeface-regular));\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.controls {\n display: flex;\n flex: 0 0 auto;\n align-items: flex-end;\n gap: 0;\n}\n/* Each arrow is a chevron on its own square, one control high at the square's foot,\n * in the title grey; the pointer fills it with the system's corners and inks it. */\n.nav {\n flex: 0 0 auto;\n width: var(--ds-unit);\n height: var(--ds-control-height);\n border-radius: var(--ds-radius);\n color: var(--ds-title-color);\n}\n.nav:hover:not(:disabled) { background: var(--ds-fill); color: var(--ds-text-color); }\n:host(:dir(rtl)) .nav > ds-icon { transform: scaleX(-1); }\n\n.grid { outline: none; }\n.weekdays,\n.week {\n display: grid;\n grid-template-columns: repeat(7, var(--ds-calendar-day));\n}\n\n/* The weekday names: a block line in the title grey, at the start of a wide day, centred on a compact one. */\n.weekday {\n box-sizing: border-box;\n height: var(--ds-unit);\n padding: calc(4px * var(--ds-sf, 1)) var(--ds-calendar-pad) 0;\n overflow: hidden;\n color: var(--ds-title-color);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n:host([compact]) .weekday { padding-inline: 0; text-align: center; }\n\n/* A day's box: hairlines on the grid lines, top and start; the last column\n * and the last week close it at the end and the foot. */\n.day {\n position: relative;\n box-sizing: border-box;\n min-width: 0;\n height: var(--ds-calendar-day-height);\n outline: none;\n}\n.day::after {\n position: absolute;\n inset: -0.5px;\n border-block-start: var(--ds-calendar-line);\n border-inline-start: var(--ds-calendar-line);\n content: \"\";\n pointer-events: none;\n}\n.day:nth-child(7)::after { border-inline-end: var(--ds-calendar-line); }\n.week:last-child .day::after { border-block-end: var(--ds-calendar-line); }\n:host([compact]) .day::after { content: none; }\n\n.day[data-day] { cursor: default; }\n:host([selectable]) .day[data-day]:not([aria-disabled=\"true\"]) { cursor: pointer; }\n:host([selectable]:not([compact])) .day[data-day]:not([aria-disabled=\"true\"]):hover { background: var(--ds-row-fill-hover, var(--ds-fill)); }\n.day:focus-visible { outline: 2px solid var(--ds-focus-ring); outline-offset: -2px; }\n:host([compact]) .day:focus-visible { outline: none; }\n:host([compact]) .day:focus-visible .date { outline: 2px solid var(--ds-focus-ring); outline-offset: -1px; }\n\n/* The date: on the first square, at the end of a wide day, in the title grey. */\n.date-line {\n box-sizing: border-box;\n display: flex;\n align-items: flex-end;\n justify-content: flex-end;\n gap: var(--ds-calendar-pad);\n height: var(--ds-unit);\n padding-inline: var(--ds-calendar-pad);\n}\n.date {\n color: var(--ds-title-color);\n font-variant-numeric: tabular-nums;\n}\n.week-number {\n margin-inline-end: auto;\n color: var(--ds-title-color);\n font-family: var(--ds-typeface-compressed);\n}\n\n/* A compact day: the date centred in its square, in the ink; with events,\n * the empty days fall back to the title grey and the busy ones keep the ink. */\n:host([compact]) .date-line { justify-content: center; padding: 0; }\n:host([compact]) .date { color: var(--ds-text-color); }\n:host([compact][data-events]) .day:not([data-busy]) .date { color: var(--ds-title-color); }\n:host([compact][selectable]) .day[data-day]:not([aria-disabled=\"true\"], [data-today], [data-selected]):hover .date { background: var(--ds-fill); }\n\n/* Today and the selected day: a disc nine tenths of a square, centred on the date's square. */\n.day:is([data-today], [data-selected]) .date-line { align-items: center; padding-inline-end: calc(var(--ds-unit) * 0.05); }\n:host([compact]) .day:is([data-today], [data-selected]) .date-line { padding: 0; }\n.date {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: var(--ds-calendar-mark);\n height: var(--ds-calendar-mark);\n border-radius: 999px;\n}\n.day:not([data-today], [data-selected]) .date { min-width: 0; height: auto; }\n:host([compact]) .day .date { min-width: var(--ds-calendar-mark); height: var(--ds-calendar-mark); }\n.day[data-today] .date { background: var(--ds-calendar-today); color: var(--ds-calendar-today-ink); letter-spacing: 0; }\n/* The selected day, and each end of a range: a square with the system's corners in the selection's blue. */\n.day[data-selected] .date { border-radius: var(--ds-radius); background: var(--ds-calendar-selected); color: var(--ds-calendar-selected-ink); letter-spacing: 0; }\n\n.day[aria-disabled=\"true\"] .date { color: var(--ds-title-color); opacity: 0.5; }\n\n/* Heat: the date's mark filled by its step, a picture's corners, inside the day's square; today and the selection draw over it. */\n.day[data-heat]:not([data-today], [data-selected]) .date-line { align-items: center; padding-inline-end: calc(var(--ds-unit) * 0.05); }\n.day[data-heat]:not([data-today], [data-selected]) .date {\n min-width: var(--ds-calendar-mark);\n height: var(--ds-calendar-mark);\n border-radius: var(--ds-radius);\n letter-spacing: 0;\n}\n.day[data-heat=\"1\"]:not([data-today], [data-selected]) .date { background: var(--ds-calendar-heat-1); color: var(--ds-calendar-heat-ink-1); }\n.day[data-heat=\"2\"]:not([data-today], [data-selected]) .date { background: var(--ds-calendar-heat-2); color: var(--ds-calendar-heat-ink-2); }\n.day[data-heat=\"3\"]:not([data-today], [data-selected]) .date { background: var(--ds-calendar-heat-3); color: var(--ds-calendar-heat-ink-3); }\n.day[data-heat=\"4\"]:not([data-today], [data-selected]) .date { background: var(--ds-calendar-heat-4); color: var(--ds-calendar-heat-ink-4); }\n:host([compact]) .day[data-heat]:not([data-today], [data-selected]) .date-line { padding: 0; }\n\n/* Events: one square each, stacked edge to edge on the day's lines, drawn one pixel short. */\n.events {\n display: flex;\n flex-direction: column;\n}\n.event,\n.more {\n box-sizing: border-box;\n display: flex;\n align-items: flex-end;\n gap: var(--ds-calendar-pad);\n height: calc(var(--ds-unit) - 1px);\n margin: 0.5px;\n padding-inline: var(--ds-calendar-pad);\n overflow: hidden;\n white-space: nowrap;\n}\n.event {\n background: var(--ds-calendar-event-fill, var(--ds-fill));\n color: var(--ds-calendar-event-ink, var(--ds-text-color));\n cursor: pointer;\n}\n.event .name { min-width: 0; overflow: hidden; text-overflow: ellipsis; }\n.event .time { flex: 0 0 auto; opacity: 0.6; font-variant-numeric: tabular-nums; }\n.more { color: var(--ds-title-color); cursor: pointer; }\n.more:hover { color: var(--ds-text-color); }\n\n/* A day whose hidden events are unfolded lays them over the days below. */\n.day[data-open] { z-index: 1; }\n.day[data-open] .events {\n position: absolute;\n inset-block-start: var(--ds-unit);\n inset-inline: 0;\n background: var(--ds-paper);\n box-shadow: 0 0 0 1px var(--ds-border-color);\n}\n\n@media (prefers-reduced-motion: no-preference) {\n .event, .more { transition: opacity 120ms ease; }\n}\n\n/* A compact day's date stands in the middle of its square once the square is two or more wide. */\n:host([compact][data-roomy]) .date-line { align-items: center; height: var(--ds-calendar-day-height); }\n\n/* The days of the months before and after, in the title grey. */\n.day[data-outside] .date { color: var(--ds-title-color); }\n:host([compact]) .day[data-outside] .date { color: var(--ds-title-color); }\n\n/* A range: the days between its ends on a band of the selection's blue; the band runs into each end's square. */\n.day[data-inside] { background: var(--ds-calendar-band); }\n:host(:not([compact])) .day:is([data-first], [data-last]) { background: var(--ds-calendar-band); }\n:host([compact]) .day[data-first] { background: linear-gradient(to right, transparent 50%, var(--ds-calendar-band) 50%); }\n:host([compact]) .day[data-last] { background: linear-gradient(to left, transparent 50%, var(--ds-calendar-band) 50%); }\n:host([compact]:dir(rtl)) .day[data-first] { background: linear-gradient(to left, transparent 50%, var(--ds-calendar-band) 50%); }\n:host([compact]:dir(rtl)) .day[data-last] { background: linear-gradient(to right, transparent 50%, var(--ds-calendar-band) 50%); }\n:host([compact][selectable]) .day[data-inside]:hover .date { background: transparent; }\n\n/* Today, as words in the title grey beside the arrows. */\n.today-button {\n height: var(--ds-control-height);\n padding-inline: calc(4px * var(--ds-sf, 1));\n border: 0;\n background: transparent;\n color: var(--ds-title-color);\n}\n.today-button:hover { background: var(--ds-fill); color: var(--ds-text-color); }\n\n/* In a compact month the pointer's day and the chosen day take squares with the system's corners; today keeps its disc. */\n:host([compact]) .date { border-radius: var(--ds-radius); }\n:host([compact]) .day[data-today]:not([data-selected]) .date { border-radius: 999px; }\n\n/* The picker: a field that opens the small month. */\n:host([picker]) {\n --ds-calendar-picker-width: calc(10 * var(--ds-unit));\n display: inline-flex;\n align-items: flex-end;\n vertical-align: bottom;\n height: var(--ds-unit);\n}\n\n.trigger {\n display: inline-flex;\n align-items: flex-end;\n gap: calc(4px * var(--ds-sf, 1));\n width: var(--ds-calendar-picker-width);\n padding-inline: 0 calc(4px * var(--ds-sf, 1));\n text-align: start;\n cursor: pointer;\n}\n.trigger:disabled { cursor: default; }\n.trigger .icon,\n.trigger .arrow { flex: 0 0 auto; }\n.trigger .text {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.trigger[data-empty] .text { color: var(--ds-title-color); }\n.trigger[aria-expanded=\"true\"] .arrow { transform: rotate(180deg); }\n\n/* The month's panel, on the menu's frame. */\n.popover {\n position: fixed;\n inset: auto;\n box-sizing: border-box;\n margin: 0;\n padding: calc(var(--ds-unit) / 2 - 1px);\n border: 1px solid var(--ds-border-color);\n border-radius: var(--ds-radius-card);\n background: var(--ds-paper);\n color: var(--ds-text-color);\n box-shadow: none;\n overflow: visible;\n}\n.popover:not(:popover-open) { display: none; }\n\n/* The days to type: a row of one square for each end, its time on the row below; one square spare after. */\n.fields { margin-block-end: var(--ds-unit); }\n.field-row {\n display: flex;\n align-items: flex-end;\n gap: calc(var(--ds-unit) / 2);\n height: var(--ds-unit);\n}\n.field { flex: 1 1 auto; min-width: 0; }\n.clock { flex: 1 1 auto; min-width: 0; }\n.fields, .options { width: calc(7 * var(--ds-unit)); }\n\n/* Include time and Clear, each one square, the words on the sixteen. */\n.option {\n box-sizing: border-box;\n display: flex;\n align-items: flex-end;\n justify-content: space-between;\n gap: var(--ds-unit);\n width: 100%;\n height: var(--ds-unit);\n margin: 0;\n padding: 0 calc(4px * var(--ds-sf, 1));\n border: 0;\n border-radius: var(--ds-radius);\n background: transparent;\n color: var(--ds-text-color);\n font: inherit;\n letter-spacing: inherit;\n text-align: start;\n cursor: pointer;\n}\n.option:hover:not(:disabled) { background: var(--ds-row-fill-hover, var(--ds-fill)); }\n.option:focus-visible { outline: 2px solid var(--ds-focus-ring); outline-offset: -2px; }\n.option:disabled { color: var(--ds-title-color); cursor: default; }\n.option .ds-switch { flex: 0 0 auto; }\n\n/* A separator: one square with a 1px line through its middle. */\n.separator {\n position: relative;\n height: var(--ds-unit);\n}\n.separator::after {\n position: absolute;\n inset-inline: 0;\n top: calc(50% - 0.5px);\n height: 1px;\n background: var(--ds-border-color);\n content: \"\";\n}\n\n@media (prefers-reduced-motion: no-preference) {\n .popover:popover-open {\n animation: ds-calendar-picker-in 140ms cubic-bezier(0.22, 1, 0.36, 1);\n }\n .trigger .arrow { transition: transform 140ms ease; }\n}\n@keyframes ds-calendar-picker-in {\n from { opacity: 0; transform: translateY(calc(-4px * var(--ds-sf, 1))); }\n to { opacity: 1; transform: none; }\n}\n";
|
|
10932
10949
|
//#endregion
|
|
10933
10950
|
//#region DS1/3-unit/ds-calendar.ts
|
|
10934
10951
|
var _Calendar;
|
|
@@ -10991,6 +11008,12 @@ var openPickers = /* @__PURE__ */ new Set();
|
|
|
10991
11008
|
* @prop {boolean} fixed - Always draw six weeks, so the month keeps its height.
|
|
10992
11009
|
* @prop {boolean} outsideDays - Draw the days of the months before and after
|
|
10993
11010
|
* in the title grey (`outside-days`); pressing one moves there.
|
|
11011
|
+
* @prop {boolean} heat - Light each day by how much happens on it, as a
|
|
11012
|
+
* contribution graph does: the events' `count`s added up (one each by
|
|
11013
|
+
* default), in four steps of the busiest day shown.
|
|
11014
|
+
* @prop {number} heatMax - The amount that lights a day fully (`heat-max`),
|
|
11015
|
+
* for a scale that stays put from month to month; the busiest day shown
|
|
11016
|
+
* by default.
|
|
10994
11017
|
* @prop {boolean} noHeader - Leave out the title and arrows (`no-header`).
|
|
10995
11018
|
* @prop {boolean} noToday - Leave out the Today button (`no-today`).
|
|
10996
11019
|
* @prop {string} min - The first day a person may choose.
|
|
@@ -11030,6 +11053,7 @@ var Calendar = class extends CalendarBase {
|
|
|
11030
11053
|
super();
|
|
11031
11054
|
this.weeksRun = "rows";
|
|
11032
11055
|
this.byDay = /* @__PURE__ */ new Map();
|
|
11056
|
+
this.heatByDay = /* @__PURE__ */ new Map();
|
|
11033
11057
|
this.internals = typeof this.attachInternals === "function" ? this.attachInternals() : null;
|
|
11034
11058
|
this.initial = "";
|
|
11035
11059
|
this.shown = false;
|
|
@@ -11169,6 +11193,7 @@ var Calendar = class extends CalendarBase {
|
|
|
11169
11193
|
this.outsideDays = false;
|
|
11170
11194
|
this.noHeader = false;
|
|
11171
11195
|
this.noToday = false;
|
|
11196
|
+
this.heat = false;
|
|
11172
11197
|
this.picker = false;
|
|
11173
11198
|
this.time = false;
|
|
11174
11199
|
this.required = false;
|
|
@@ -11291,13 +11316,15 @@ var Calendar = class extends CalendarBase {
|
|
|
11291
11316
|
const unfolded = this.unfolded === day;
|
|
11292
11317
|
const shown = unfolded || events.length <= lines ? events : events.slice(0, Math.max(0, lines - 1));
|
|
11293
11318
|
const hidden = events.length - shown.length;
|
|
11319
|
+
const heat = this.heatByDay.get(day);
|
|
11294
11320
|
return b$1`<div
|
|
11295
11321
|
role="gridcell"
|
|
11296
11322
|
class="day"
|
|
11297
11323
|
part=${[
|
|
11298
11324
|
"day",
|
|
11299
11325
|
isToday ? "today" : "",
|
|
11300
|
-
selected ? "selected" : ""
|
|
11326
|
+
selected ? "selected" : "",
|
|
11327
|
+
heat ? "heat" : ""
|
|
11301
11328
|
].filter(Boolean).join(" ")}
|
|
11302
11329
|
data-day=${day}
|
|
11303
11330
|
tabindex=${!outside && day === this.tabDay ? 0 : -1}
|
|
@@ -11312,6 +11339,7 @@ var Calendar = class extends CalendarBase {
|
|
|
11312
11339
|
?data-last=${last}
|
|
11313
11340
|
?data-outside=${outside}
|
|
11314
11341
|
?data-busy=${events.length > 0}
|
|
11342
|
+
data-heat=${heat ?? A}
|
|
11315
11343
|
?data-open=${unfolded}
|
|
11316
11344
|
>
|
|
11317
11345
|
<span class="date-line" aria-hidden="true">
|
|
@@ -11335,6 +11363,7 @@ var Calendar = class extends CalendarBase {
|
|
|
11335
11363
|
const first = this.firstDay;
|
|
11336
11364
|
const weeks = monthWeeks(month, first, this.fixed);
|
|
11337
11365
|
this.byDay = eventsByDay(this.events ?? [], weeks[0][0], weeks.at(-1)[6]);
|
|
11366
|
+
this.heatByDay = this.heat ? heatLevels(new Map([...this.byDay].filter(([day]) => sameMonth(day, month))), this.heatMax) : /* @__PURE__ */ new Map();
|
|
11338
11367
|
const short = this.compact ? this.squaresPerDay < 2 ? weekdayNames(first, "narrow") : weekdayNames(first, "short").map((name) => /^\p{Script=Latin}/u.test(name) ? name.replace(/\.$/, "").slice(0, 2) : name) : weekdayNames(first, "short");
|
|
11339
11368
|
const long = weekdayNames(first, "long");
|
|
11340
11369
|
return b$1`<div class="calendar" part="calendar" @focusout=${this.onFocusOut} @pointerover=${this.onPointerOver} @pointerleave=${() => this.hoverDay = void 0}>
|
|
@@ -11637,6 +11666,14 @@ _Calendar.properties = {
|
|
|
11637
11666
|
attribute: "no-today",
|
|
11638
11667
|
reflect: true
|
|
11639
11668
|
},
|
|
11669
|
+
heat: {
|
|
11670
|
+
type: Boolean,
|
|
11671
|
+
reflect: true
|
|
11672
|
+
},
|
|
11673
|
+
heatMax: {
|
|
11674
|
+
type: Number,
|
|
11675
|
+
attribute: "heat-max"
|
|
11676
|
+
},
|
|
11640
11677
|
picker: {
|
|
11641
11678
|
type: Boolean,
|
|
11642
11679
|
reflect: true
|