@k2b/ui 0.47.0 → 0.49.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.
Files changed (95) hide show
  1. package/dist/browser/actions/CopyButton.js +26 -18
  2. package/dist/browser/actions/CopyButton.js.map +1 -1
  3. package/dist/browser/chat/ChatComposer.js +244 -193
  4. package/dist/browser/chat/ChatComposer.js.map +1 -1
  5. package/dist/browser/chat/chat-messages.js +6 -0
  6. package/dist/browser/chat/chat-messages.js.map +1 -1
  7. package/dist/browser/chat/types.js.map +1 -1
  8. package/dist/browser/content/Calendar.js +40 -5
  9. package/dist/browser/content/Calendar.js.map +1 -1
  10. package/dist/browser/content/calendar-event-detail.js +328 -0
  11. package/dist/browser/content/calendar-event-detail.js.map +1 -0
  12. package/dist/browser/content/calendar-messages.js +34 -2
  13. package/dist/browser/content/calendar-messages.js.map +1 -1
  14. package/dist/browser/content/calendar-shared.js +189 -82
  15. package/dist/browser/content/calendar-shared.js.map +1 -1
  16. package/dist/browser/content/calendar-time-view.js +101 -96
  17. package/dist/browser/content/calendar-time-view.js.map +1 -1
  18. package/dist/browser/content/index.js.map +1 -1
  19. package/dist/browser/feedback/prompt-confirm.js +7 -4
  20. package/dist/browser/feedback/prompt-confirm.js.map +1 -1
  21. package/dist/browser/feedback/prompts.js +3 -3
  22. package/dist/browser/feedback/prompts.js.map +1 -1
  23. package/dist/browser/inputs/NumberInput.js +17 -5
  24. package/dist/browser/inputs/NumberInput.js.map +1 -1
  25. package/dist/browser/inputs/dictation/Dictation.js +114 -108
  26. package/dist/browser/inputs/dictation/Dictation.js.map +1 -1
  27. package/dist/browser/inputs/dictation/dictation-messages.js +2 -0
  28. package/dist/browser/inputs/dictation/dictation-messages.js.map +1 -1
  29. package/dist/browser/layout/AppWorkspace.js +574 -522
  30. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  31. package/dist/browser/layout/MobileShell.js +26 -0
  32. package/dist/browser/layout/MobileShell.js.map +1 -1
  33. package/dist/browser/layout/index.js +1 -0
  34. package/dist/browser/layout/index.js.map +1 -1
  35. package/dist/browser/layout/sheet-handle.js +155 -0
  36. package/dist/browser/layout/sheet-handle.js.map +1 -0
  37. package/dist/browser/surfaces/NoticeCard.js +48 -29
  38. package/dist/browser/surfaces/NoticeCard.js.map +1 -1
  39. package/dist/ssr/actions/CopyButton.js +13 -8
  40. package/dist/ssr/actions/CopyButton.js.map +1 -1
  41. package/dist/ssr/chat/ChatComposer.js +53 -30
  42. package/dist/ssr/chat/ChatComposer.js.map +1 -1
  43. package/dist/ssr/chat/chat-messages.js +6 -0
  44. package/dist/ssr/chat/chat-messages.js.map +1 -1
  45. package/dist/ssr/chat/types.js.map +1 -1
  46. package/dist/ssr/content/Calendar.js +36 -4
  47. package/dist/ssr/content/Calendar.js.map +1 -1
  48. package/dist/ssr/content/calendar-event-detail.js +212 -0
  49. package/dist/ssr/content/calendar-event-detail.js.map +1 -0
  50. package/dist/ssr/content/calendar-messages.js +34 -2
  51. package/dist/ssr/content/calendar-messages.js.map +1 -1
  52. package/dist/ssr/content/calendar-shared.js +117 -36
  53. package/dist/ssr/content/calendar-shared.js.map +1 -1
  54. package/dist/ssr/content/calendar-time-view.js +6 -4
  55. package/dist/ssr/content/calendar-time-view.js.map +1 -1
  56. package/dist/ssr/content/index.js.map +1 -1
  57. package/dist/ssr/feedback/prompt-confirm.js +7 -4
  58. package/dist/ssr/feedback/prompt-confirm.js.map +1 -1
  59. package/dist/ssr/feedback/prompts.js +3 -3
  60. package/dist/ssr/feedback/prompts.js.map +1 -1
  61. package/dist/ssr/inputs/NumberInput.js +17 -5
  62. package/dist/ssr/inputs/NumberInput.js.map +1 -1
  63. package/dist/ssr/inputs/dictation/Dictation.js +3 -1
  64. package/dist/ssr/inputs/dictation/Dictation.js.map +1 -1
  65. package/dist/ssr/inputs/dictation/dictation-messages.js +2 -0
  66. package/dist/ssr/inputs/dictation/dictation-messages.js.map +1 -1
  67. package/dist/ssr/layout/AppWorkspace.js +152 -114
  68. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  69. package/dist/ssr/layout/MobileShell.js +26 -0
  70. package/dist/ssr/layout/MobileShell.js.map +1 -1
  71. package/dist/ssr/layout/index.js +1 -0
  72. package/dist/ssr/layout/index.js.map +1 -1
  73. package/dist/ssr/layout/sheet-handle.js +155 -0
  74. package/dist/ssr/layout/sheet-handle.js.map +1 -0
  75. package/dist/ssr/surfaces/NoticeCard.js +25 -10
  76. package/dist/ssr/surfaces/NoticeCard.js.map +1 -1
  77. package/dist/styles.css +1 -1
  78. package/dist/types/chat/chat-messages.d.ts +3 -0
  79. package/dist/types/chat/types.d.ts +5 -0
  80. package/dist/types/content/Calendar.d.ts +29 -5
  81. package/dist/types/content/calendar-event-detail.d.ts +21 -0
  82. package/dist/types/content/calendar-messages.d.ts +16 -0
  83. package/dist/types/content/calendar-shared.d.ts +16 -1
  84. package/dist/types/content/calendar-time-view.d.ts +1 -1
  85. package/dist/types/content/index.d.ts +1 -1
  86. package/dist/types/feedback/prompt-confirm.d.ts +3 -1
  87. package/dist/types/feedback/prompts.d.ts +2 -2
  88. package/dist/types/inputs/NumberInput.d.ts +1 -1
  89. package/dist/types/inputs/dictation/dictation-messages.d.ts +1 -0
  90. package/dist/types/layout/AppWorkspace.d.ts +16 -1
  91. package/dist/types/layout/MobileShell.d.ts +5 -0
  92. package/dist/types/layout/index.d.ts +2 -1
  93. package/dist/types/layout/sheet-handle.d.ts +21 -0
  94. package/dist/types/surfaces/NoticeCard.d.ts +5 -2
  95. package/package.json +1 -1
@@ -3,24 +3,29 @@ import { runHydrationEvents as _$runHydrationEvents } from "solid-js/web";
3
3
  import { spread as _$spread } from "solid-js/web";
4
4
  import { mergeProps as _$mergeProps } from "solid-js/web";
5
5
  import { getNextMarker as _$getNextMarker } from "solid-js/web";
6
+ import { insert as _$insert } from "solid-js/web";
6
7
  import { memo as _$memo } from "solid-js/web";
7
8
  import { createComponent as _$createComponent } from "solid-js/web";
9
+ import { className as _$className } from "solid-js/web";
10
+ import { effect as _$effect } from "solid-js/web";
8
11
  import { getNextElement as _$getNextElement } from "solid-js/web";
9
- import { insert as _$insert } from "solid-js/web";
10
- var _tmpl$ = /*#__PURE__*/_$template(`<span class=k2b-calendar-event__time>`),
11
- _tmpl$2 = /*#__PURE__*/_$template(`<span class=k2b-calendar-event__marker aria-hidden=true>`),
12
- _tmpl$3 = /*#__PURE__*/_$template(`<span class=k2b-calendar-event__title><!$><!/><!$><!/>`),
13
- _tmpl$4 = /*#__PURE__*/_$template(`<span class=k2b-calendar-event__remaining>`),
14
- _tmpl$5 = /*#__PURE__*/_$template(`<span class=k2b-calendar-event__meta><!$><!/><!$><!/>`),
15
- _tmpl$6 = /*#__PURE__*/_$template(`<span class=k2b-calendar-event__meta>`),
16
- _tmpl$7 = /*#__PURE__*/_$template(`<span class=k2b-calendar-event__description>`),
17
- _tmpl$8 = /*#__PURE__*/_$template(`<span class=k2b-calendar-event__hint data-edge=start aria-hidden=true>`),
18
- _tmpl$9 = /*#__PURE__*/_$template(`<span class=k2b-calendar-event__hint data-edge=end aria-hidden=true>`),
19
- _tmpl$0 = /*#__PURE__*/_$template(`<a>`),
20
- _tmpl$1 = /*#__PURE__*/_$template(`<button>`),
21
- _tmpl$10 = /*#__PURE__*/_$template(`<div>`);
12
+ var _tmpl$ = /*#__PURE__*/_$template(`<i aria-hidden=true>`),
13
+ _tmpl$2 = /*#__PURE__*/_$template(`<span class=k2b-calendar-event__remaining>`),
14
+ _tmpl$3 = /*#__PURE__*/_$template(`<span class=k2b-calendar-event__links><i class="ti ti-link"></i><!$><!/>`),
15
+ _tmpl$4 = /*#__PURE__*/_$template(`<span class=k2b-calendar-event__extras aria-hidden=true><!$><!/><!$><!/>`),
16
+ _tmpl$5 = /*#__PURE__*/_$template(`<span class=k2b-calendar-event__time>`),
17
+ _tmpl$6 = /*#__PURE__*/_$template(`<span class=k2b-calendar-event__title><!$><!/><!$><!/>`),
18
+ _tmpl$7 = /*#__PURE__*/_$template(`<span class=k2b-calendar-event__meta>`),
19
+ _tmpl$8 = /*#__PURE__*/_$template(`<span class=k2b-calendar-event__row><!$><!/><!$><!/>`),
20
+ _tmpl$9 = /*#__PURE__*/_$template(`<span class=k2b-calendar-event__description>`),
21
+ _tmpl$0 = /*#__PURE__*/_$template(`<span class=k2b-calendar-event__hint data-edge=start aria-hidden=true>`),
22
+ _tmpl$1 = /*#__PURE__*/_$template(`<span class=k2b-calendar-event__hint data-edge=end aria-hidden=true>`),
23
+ _tmpl$10 = /*#__PURE__*/_$template(`<a>`),
24
+ _tmpl$11 = /*#__PURE__*/_$template(`<button>`),
25
+ _tmpl$12 = /*#__PURE__*/_$template(`<div>`);
22
26
  import { dates as calendar } from "@k2b/stdlib";
23
27
  import { createMemo, Show } from "solid-js";
28
+ import { AvatarFaces } from "../surfaces/AvatarStack";
24
29
  import { useCalendarMessages } from "./calendar-messages";
25
30
 
26
31
  /** One piece of an event in one day, with the times of the whole event. */
@@ -29,6 +34,24 @@ import { useCalendarMessages } from "./calendar-messages";
29
34
 
30
35
  /** What the built-in views read from the props: they only ever link to built-in views. */
31
36
 
37
+ /** `data` keys the calendar writes as `data-*` attributes: camelCase letters and digits, none of the calendar's own. */
38
+ const DATA_KEY = /^[a-z][a-zA-Z0-9]*$/;
39
+ export const eventDataAttributes = data => {
40
+ const attributes = {};
41
+ for (const [key, value] of Object.entries(data ?? {})) {
42
+ if (!DATA_KEY.test(key) || key.startsWith("calendar") || typeof value !== "string") continue;
43
+ attributes[`data-${key.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`)}`] = value;
44
+ }
45
+ return attributes;
46
+ };
47
+
48
+ /** An open to-do or deadline whose time has passed. */
49
+ export const isOverdue = (event, now) => {
50
+ if (event.checked !== false || !now) return false;
51
+ const start = event.sourceStartDate?.getTime() ?? Number.NaN;
52
+ const end = event.sourceEndDate?.getTime() ?? start;
53
+ return Math.max(start, end) <= now.getTime();
54
+ };
32
55
  export const ownerDateConfig = owner => ({
33
56
  ...owner.dateConfig,
34
57
  timeZone: owner.timeZone ?? owner.dateConfig?.timeZone,
@@ -75,7 +98,15 @@ export const EventChip = props => {
75
98
  const style = () => props.event.colorHex ? {
76
99
  "--k2b-calendar-accent": props.event.colorHex
77
100
  } : undefined;
78
- const isInteractive = () => Boolean(props.owner.onEventActivate);
101
+ const activate = anchor => {
102
+ if (props.owner.onEventActivate) props.owner.onEventActivate(props.event);else props.owner.openEventDetail?.(props.event, anchor);
103
+ };
104
+ const isInteractive = () => Boolean(props.owner.onEventActivate ?? props.owner.openEventDetail);
105
+ const done = () => props.event.checked === true;
106
+ const overdue = () => isOverdue(props.event, props.owner.calendarNow?.());
107
+ const attendees = () => props.event.attendees ?? [];
108
+ const links = () => props.event.links ?? [];
109
+ const shownFaces = () => props.faces ? attendees().slice(0, props.faces) : [];
79
110
  const durationHours = () => (props.event.endDate.getTime() - props.event.startDate.getTime()) / 3_600_000;
80
111
  const short = () => Boolean(props.fill && !props.event.allDay && durationHours() < 0.75);
81
112
  const showTime = () => props.timeLabel ? !props.event.allDay : !props.event.allDay && !props.compact && durationHours() >= 0.75;
@@ -90,7 +121,11 @@ export const EventChip = props => {
90
121
  start: formatTime(props.event.startDate, dateConfig()),
91
122
  end: formatTime(props.event.endDate, dateConfig())
92
123
  });
93
- return [label, props.remaining, props.event.accessibleDetail].filter(Boolean).join(", ");
124
+ return [label, props.remaining, done() ? messages().calendarStateDone : overdue() ? messages().calendarStateOverdue : undefined, attendees().length ? messages().calendarPeopleCount({
125
+ count: attendees().length
126
+ }) : undefined, links().length ? messages().calendarLinkCount({
127
+ count: links().length
128
+ }) : undefined, props.event.accessibleDetail].filter(Boolean).join(", ");
94
129
  };
95
130
  const renderedEvent = () => props.owner.renderEvent?.(props.event, {
96
131
  compact: props.compact ?? false,
@@ -105,81 +140,151 @@ export const EventChip = props => {
105
140
  checkbox: props.checkbox ?? false,
106
141
  timeline: props.timeline ?? false
107
142
  });
143
+ // Faces and the link count only take room the title and time leave; they carry no text of their own.
144
+ const icon = () => props.event.icon ? (() => {
145
+ var _el$ = _$getNextElement(_tmpl$);
146
+ _$effect(() => _$className(_el$, `k2b-calendar-event__icon ${props.event.icon}`));
147
+ return _el$;
148
+ })() : undefined;
149
+ const metaText = () => [_$createComponent(Show, {
150
+ get when() {
151
+ return showTime();
152
+ },
153
+ get children() {
154
+ return timeLabel();
155
+ }
156
+ }), _$createComponent(Show, {
157
+ get when() {
158
+ return props.remaining;
159
+ },
160
+ get children() {
161
+ var _el$2 = _$getNextElement(_tmpl$2);
162
+ _$insert(_el$2, (() => {
163
+ var _c$ = _$memo(() => !!showTime());
164
+ return () => _c$() ? ` · ${props.remaining}` : props.remaining;
165
+ })());
166
+ return _el$2;
167
+ }
168
+ })];
169
+ const hasExtras = () => shownFaces().length > 0 || Boolean(props.linkCount && links().length > 0);
170
+ const extras = () => hasExtras() ? (() => {
171
+ var _el$3 = _$getNextElement(_tmpl$4),
172
+ _el$8 = _el$3.firstChild,
173
+ [_el$9, _co$2] = _$getNextMarker(_el$8.nextSibling),
174
+ _el$0 = _el$9.nextSibling,
175
+ [_el$1, _co$3] = _$getNextMarker(_el$0.nextSibling);
176
+ _$insert(_el$3, _$createComponent(Show, {
177
+ get when() {
178
+ return shownFaces().length > 0;
179
+ },
180
+ get children() {
181
+ return _$createComponent(AvatarFaces, {
182
+ get people() {
183
+ return shownFaces();
184
+ },
185
+ get total() {
186
+ return _$memo(() => (props.faces ?? 0) > 1)() ? attendees().length : undefined;
187
+ },
188
+ get max() {
189
+ return props.faces;
190
+ }
191
+ });
192
+ }
193
+ }), _el$9, _co$2);
194
+ _$insert(_el$3, _$createComponent(Show, {
195
+ get when() {
196
+ return _$memo(() => !!props.linkCount)() && links().length > 0;
197
+ },
198
+ get children() {
199
+ var _el$4 = _$getNextElement(_tmpl$3),
200
+ _el$5 = _el$4.firstChild,
201
+ _el$6 = _el$5.nextSibling,
202
+ [_el$7, _co$] = _$getNextMarker(_el$6.nextSibling);
203
+ _$insert(_el$4, () => links().length, _el$7, _co$);
204
+ return _el$4;
205
+ }
206
+ }), _el$1, _co$3);
207
+ return _el$3;
208
+ })() : undefined;
108
209
  const defaultContent = [_$createComponent(Show, {
109
210
  get when() {
110
211
  return props.leadingTime;
111
212
  },
112
213
  get children() {
113
- var _el$ = _$getNextElement(_tmpl$);
114
- _$insert(_el$, () => props.leadingTime);
115
- return _el$;
214
+ return [_$memo(() => icon()), (() => {
215
+ var _el$10 = _$getNextElement(_tmpl$5);
216
+ _$insert(_el$10, () => props.leadingTime);
217
+ return _el$10;
218
+ })()];
116
219
  }
117
220
  }), (() => {
118
- var _el$2 = _$getNextElement(_tmpl$3),
119
- _el$4 = _el$2.firstChild,
120
- [_el$5, _co$] = _$getNextMarker(_el$4.nextSibling),
121
- _el$6 = _el$5.nextSibling,
122
- [_el$7, _co$2] = _$getNextMarker(_el$6.nextSibling);
123
- _$insert(_el$2, _$createComponent(Show, {
221
+ var _el$11 = _$getNextElement(_tmpl$6),
222
+ _el$12 = _el$11.firstChild,
223
+ [_el$13, _co$4] = _$getNextMarker(_el$12.nextSibling),
224
+ _el$14 = _el$13.nextSibling,
225
+ [_el$15, _co$5] = _$getNextMarker(_el$14.nextSibling);
226
+ _$insert(_el$11, _$createComponent(Show, {
124
227
  get when() {
125
- return _$memo(() => props.event.display === "marker")() && !props.checkbox;
228
+ return !props.leadingTime;
126
229
  },
127
230
  get children() {
128
- return _$getNextElement(_tmpl$2);
231
+ return icon();
129
232
  }
130
- }), _el$5, _co$);
131
- _$insert(_el$2, () => props.event.title, _el$7, _co$2);
132
- return _el$2;
233
+ }), _el$13, _co$4);
234
+ _$insert(_el$11, () => props.event.title, _el$15, _co$5);
235
+ return _el$11;
133
236
  })(), _$createComponent(Show, {
134
237
  get when() {
135
- return showTime() || props.remaining;
238
+ return hasExtras();
136
239
  },
137
- get children() {
138
- var _el$8 = _$getNextElement(_tmpl$5),
139
- _el$0 = _el$8.firstChild,
140
- [_el$1, _co$3] = _$getNextMarker(_el$0.nextSibling),
141
- _el$10 = _el$1.nextSibling,
142
- [_el$11, _co$4] = _$getNextMarker(_el$10.nextSibling);
143
- _$insert(_el$8, _$createComponent(Show, {
240
+ get fallback() {
241
+ return _$createComponent(Show, {
144
242
  get when() {
145
- return showTime();
243
+ return showTime() || props.remaining;
146
244
  },
147
245
  get children() {
148
- return timeLabel();
246
+ var _el$24 = _$getNextElement(_tmpl$7);
247
+ _$insert(_el$24, metaText);
248
+ return _el$24;
149
249
  }
150
- }), _el$1, _co$3);
151
- _$insert(_el$8, _$createComponent(Show, {
250
+ });
251
+ },
252
+ get children() {
253
+ var _el$16 = _$getNextElement(_tmpl$8),
254
+ _el$18 = _el$16.firstChild,
255
+ [_el$19, _co$6] = _$getNextMarker(_el$18.nextSibling),
256
+ _el$20 = _el$19.nextSibling,
257
+ [_el$21, _co$7] = _$getNextMarker(_el$20.nextSibling);
258
+ _$insert(_el$16, _$createComponent(Show, {
152
259
  get when() {
153
- return props.remaining;
260
+ return showTime() || props.remaining;
154
261
  },
155
262
  get children() {
156
- var _el$9 = _$getNextElement(_tmpl$4);
157
- _$insert(_el$9, (() => {
158
- var _c$ = _$memo(() => !!showTime());
159
- return () => _c$() ? ` · ${props.remaining}` : props.remaining;
160
- })());
161
- return _el$9;
263
+ var _el$17 = _$getNextElement(_tmpl$7);
264
+ _$insert(_el$17, metaText);
265
+ return _el$17;
162
266
  }
163
- }), _el$11, _co$4);
164
- return _el$8;
267
+ }), _el$19, _co$6);
268
+ _$insert(_el$16, extras, _el$21, _co$7);
269
+ return _el$16;
165
270
  }
166
271
  }), _$createComponent(Show, {
167
272
  get when() {
168
273
  return showLocation();
169
274
  },
170
275
  get children() {
171
- var _el$12 = _$getNextElement(_tmpl$6);
172
- _$insert(_el$12, () => props.event.location);
173
- return _el$12;
276
+ var _el$22 = _$getNextElement(_tmpl$7);
277
+ _$insert(_el$22, () => props.event.location);
278
+ return _el$22;
174
279
  }
175
280
  }), _$createComponent(Show, {
176
281
  get when() {
177
282
  return showDescription();
178
283
  },
179
284
  get children() {
180
- var _el$13 = _$getNextElement(_tmpl$7);
181
- _$insert(_el$13, () => props.event.description);
182
- return _el$13;
285
+ var _el$23 = _$getNextElement(_tmpl$9);
286
+ _$insert(_el$23, () => props.event.description);
287
+ return _el$23;
183
288
  }
184
289
  })];
185
290
  const content = () => [_$createComponent(Show, {
@@ -187,18 +292,18 @@ export const EventChip = props => {
187
292
  return props.hintStart;
188
293
  },
189
294
  get children() {
190
- var _el$14 = _$getNextElement(_tmpl$8);
191
- _$insert(_el$14, () => props.hintStart);
192
- return _el$14;
295
+ var _el$25 = _$getNextElement(_tmpl$0);
296
+ _$insert(_el$25, () => props.hintStart);
297
+ return _el$25;
193
298
  }
194
299
  }), _$memo(() => renderedEvent() ?? defaultContent), _$createComponent(Show, {
195
300
  get when() {
196
301
  return props.hintEnd;
197
302
  },
198
303
  get children() {
199
- var _el$15 = _$getNextElement(_tmpl$9);
200
- _$insert(_el$15, () => props.hintEnd);
201
- return _el$15;
304
+ var _el$26 = _$getNextElement(_tmpl$1);
305
+ _$insert(_el$26, () => props.hintEnd);
306
+ return _el$26;
202
307
  }
203
308
  }), _$memo(() => props.trailing)];
204
309
  const isActionable = () => isInteractive() || Boolean(props.onMovePointerDown);
@@ -209,16 +314,18 @@ export const EventChip = props => {
209
314
  event.stopPropagation();
210
315
  return;
211
316
  }
212
- if (!props.owner.onEventActivate || props.owner.eventActivation === "double") return;
317
+ if (!isInteractive() || props.owner.eventActivation === "double") return;
318
+ // A link with a modifier or another button still opens where the reader asked, such as in a new tab.
319
+ if (props.href && (event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)) return;
213
320
  event.preventDefault();
214
321
  event.stopPropagation();
215
- props.owner.onEventActivate(props.event);
322
+ activate(event.currentTarget);
216
323
  };
217
324
  const onDoubleClick = event => {
218
- if (!props.owner.onEventActivate || props.owner.eventActivation !== "double") return;
325
+ if (!isInteractive() || props.owner.eventActivation !== "double") return;
219
326
  event.preventDefault();
220
327
  event.stopPropagation();
221
- props.owner.onEventActivate(props.event);
328
+ activate(event.currentTarget);
222
329
  };
223
330
  /** Space on an entry with a box checks it; Enter still opens the entry. */
224
331
  const onCheckKeyDown = event => {
@@ -230,7 +337,7 @@ export const EventChip = props => {
230
337
  const onButtonKeyDown = event => {
231
338
  if (onCheckKeyDown(event) || !isInteractive() || event.key !== "Enter" && event.key !== " ") return;
232
339
  event.preventDefault();
233
- props.owner.onEventActivate?.(props.event);
340
+ activate(event.currentTarget);
234
341
  };
235
342
  const onPointerDown = event => {
236
343
  if (event.pointerType === "touch") return;
@@ -252,6 +359,9 @@ export const EventChip = props => {
252
359
  "data-continues-after": props.continuesAfter ? "true" : undefined,
253
360
  "data-bar": props.bar ? "true" : undefined,
254
361
  "data-display": props.event.display,
362
+ "data-done": done() ? "true" : undefined,
363
+ "data-overdue": overdue() ? "true" : undefined,
364
+ ...eventDataAttributes(props.event.data),
255
365
  "data-stop": props.stop?.id,
256
366
  "data-col": props.stop?.column,
257
367
  "data-minute": props.stop?.minute,
@@ -259,17 +369,14 @@ export const EventChip = props => {
259
369
  "aria-label": ariaLabel()
260
370
  });
261
371
  return props.href ? (() => {
262
- var _el$16 = _$getNextElement(_tmpl$0);
263
- _$spread(_el$16, _$mergeProps(attributes, {
372
+ var _el$27 = _$getNextElement(_tmpl$10);
373
+ _$spread(_el$27, _$mergeProps(attributes, {
264
374
  get href() {
265
375
  return props.href;
266
376
  },
267
377
  get ["data-interactive"]() {
268
378
  return isInteractive() ? "true" : undefined;
269
379
  },
270
- get ["data-space-item-id"]() {
271
- return props.event.dataSpaceItemId;
272
- },
273
380
  get tabIndex() {
274
381
  return props.tabIndex;
275
382
  },
@@ -284,12 +391,12 @@ export const EventChip = props => {
284
391
  "onPointerDown": onPointerDown,
285
392
  "onKeyDown": onCheckKeyDown
286
393
  }), false, true);
287
- _$insert(_el$16, content);
394
+ _$insert(_el$27, content);
288
395
  _$runHydrationEvents();
289
- return _el$16;
396
+ return _el$27;
290
397
  })() : isActionable() ? (() => {
291
- var _el$17 = _$getNextElement(_tmpl$1);
292
- _$spread(_el$17, _$mergeProps(attributes, {
398
+ var _el$28 = _$getNextElement(_tmpl$11);
399
+ _$spread(_el$28, _$mergeProps(attributes, {
293
400
  "type": "button",
294
401
  "data-interactive": "true",
295
402
  get tabIndex() {
@@ -300,21 +407,21 @@ export const EventChip = props => {
300
407
  "onPointerDown": onPointerDown,
301
408
  "onKeyDown": onButtonKeyDown
302
409
  }), false, true);
303
- _$insert(_el$17, content);
410
+ _$insert(_el$28, content);
304
411
  _$runHydrationEvents();
305
- return _el$17;
412
+ return _el$28;
306
413
  })() : (() => {
307
- var _el$18 = _$getNextElement(_tmpl$10);
308
- _$spread(_el$18, _$mergeProps(attributes, {
414
+ var _el$29 = _$getNextElement(_tmpl$12);
415
+ _$spread(_el$29, _$mergeProps(attributes, {
309
416
  "role": "group",
310
417
  get tabIndex() {
311
418
  return props.tabIndex;
312
419
  },
313
420
  "onKeyDown": onCheckKeyDown
314
421
  }), false, true);
315
- _$insert(_el$18, content);
422
+ _$insert(_el$29, content);
316
423
  _$runHydrationEvents();
317
- return _el$18;
424
+ return _el$29;
318
425
  })();
319
426
  };
320
427
  let measureContext;
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["content/calendar-shared.tsx"],"sourcesContent":["import { dates as calendar, type DateContext } from \"@k2b/stdlib\";\nimport type { JSX } from \"solid-js\";\nimport { createMemo, Show } from \"solid-js\";\nimport type { CalendarEvent, CalendarProps } from \"./Calendar\";\nimport { useCalendarMessages } from \"./calendar-messages\";\n\n/** One piece of an event in one day, with the times of the whole event. */\nexport type NormalizedEvent = CalendarEvent & {\n startDate: Date;\n endDate: Date;\n dayKey: string;\n sourceStartDate: Date;\n sourceEndDate: Date;\n};\n\n/** A keyboard stop of the week grid. */\nexport type CalendarStop = { id: string; column: number; minute: number };\n\n/** What the built-in views read from the props: they only ever link to built-in views. */\nexport type CalendarOwner = Omit<CalendarProps, \"view\" | \"customViews\" | \"children\">;\n\nexport const ownerDateConfig = (owner: CalendarOwner): DateContext => ({\n ...owner.dateConfig,\n timeZone: owner.timeZone ?? owner.dateConfig?.timeZone,\n firstDayOfWeek: owner.firstDayOfWeek ?? owner.dateConfig?.firstDayOfWeek ?? owner.dateConfig?.weekStartsOn ?? 1,\n});\n\nconst dateOnlyPattern = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nexport const parseDate = (value: Date | string, context?: DateContext): Date => {\n if (value instanceof Date) return new Date(value);\n if (dateOnlyPattern.test(value)) return calendar.parseCalendarDate(value, context);\n const normalized = value.includes(\"T\") ? value : value.replace(\" \", \"T\");\n const parsed = new Date(normalized);\n if (!Number.isNaN(parsed.getTime())) return parsed;\n const [year, month = \"1\", day = \"1\"] = value.split(\"-\");\n return new Date(Number(year), Number(month) - 1, Number(day), 12);\n};\n\nexport const validDate = (value: Date): boolean => !Number.isNaN(value.getTime());\n\nexport const formatTime = (date: Date, context?: DateContext): string => calendar.formatTime(date, context);\n\nexport const eventHref = (props: CalendarOwner, event: CalendarEvent): string | undefined => props.getEventHref?.(event) ?? event.href;\n\n/** Places a calendar popover below its anchor when there is room and above it otherwise, inside the viewport. */\nexport const placeCalendarPopover = (anchor: Element | DOMRect, popover: HTMLElement): void => {\n const margin = 8;\n const gap = 4;\n const rect = anchor instanceof Element ? anchor.getBoundingClientRect() : anchor;\n const width = Math.min(popover.offsetWidth || 288, window.innerWidth - margin * 2);\n const height = popover.offsetHeight;\n const left = Math.max(margin, Math.min(rect.left, window.innerWidth - width - margin));\n const roomBelow = window.innerHeight - rect.bottom - gap - margin;\n const above = height > roomBelow && rect.top - gap - margin > roomBelow;\n const top = above ? Math.max(margin, rect.top - height - gap) : Math.min(rect.bottom + gap, window.innerHeight - height - margin);\n popover.style.left = `${left}px`;\n popover.style.top = `${Math.max(margin, top)}px`;\n};\n\n/** Follows a calendar link the way the calendar's own links do: through the host's navigation when it has one. */\nexport const followCalendarHref = (owner: CalendarOwner, href: string): void => {\n if (owner.onNavigateHref) owner.onNavigateHref(href);\n else window.location.assign(href);\n};\n\nexport const EventChip = (props: {\n event: NormalizedEvent;\n owner: CalendarOwner;\n href?: string;\n compact?: boolean;\n fill?: boolean;\n moving?: boolean;\n /** Replaces the title and time at the start of the accessible name, for example with the dates a long event spans. */\n label?: string;\n /** A bar of a long event that goes on before or after the week row it sits in. */\n continuesBefore?: boolean;\n continuesAfter?: boolean;\n /** Month view: an all-day or multi-day entry drawn as a bar. */\n bar?: boolean;\n /** Short dates at the torn ends of a bar, where it continues in another week row. */\n hintStart?: string;\n hintEnd?: string;\n /** Month view: the start time before the title. */\n leadingTime?: string;\n /** Day and week views: what is left of a running event, such as \"27 min left\". */\n remaining?: string;\n /** Day and week views: the calendar draws the event's checkbox beside the chip. */\n checkbox?: boolean;\n /** Day and week views with `dayHours`: the chip is a band, a deadline, or an all-day entry of a timeline. */\n timeline?: boolean;\n /** Text after the content, such as the time of a deadline. */\n trailing?: JSX.Element;\n /** Day and week views: the time as they write it, such as \"10:30–11:15\", shown whatever the length. */\n timeLabel?: string;\n /** Day view: a band tall enough shows its place below the time. */\n showLocation?: boolean;\n /** Week view: the grid's one tab stop decides which chip takes Tab. */\n tabIndex?: number;\n /** A keyboard stop of the week grid: its id, its day column, and its minute for moving between columns. */\n stop?: CalendarStop;\n /** Day and week views: Space on the chip checks the box the calendar draws beside it, as on the box itself. */\n onCheck?: () => void;\n onMovePointerDown?: (event: PointerEvent, onActivate: () => void) => void;\n}): JSX.Element => {\n const messages = useCalendarMessages();\n const dateConfig = createMemo(() => ownerDateConfig(props.owner));\n const color = () => props.event.color ?? \"blue\";\n const selected = () => Boolean(props.owner.selectedEventId) && props.owner.selectedEventId === props.event.id;\n const style = () => (props.event.colorHex ? { \"--k2b-calendar-accent\": props.event.colorHex } : undefined);\n const isInteractive = () => Boolean(props.owner.onEventActivate);\n const durationHours = () => (props.event.endDate.getTime() - props.event.startDate.getTime()) / 3_600_000;\n const short = () => Boolean(props.fill && !props.event.allDay && durationHours() < 0.75);\n const showTime = () => (props.timeLabel ? !props.event.allDay : !props.event.allDay && !props.compact && durationHours() >= 0.75);\n const showLocation = () =>\n Boolean(props.event.location && (props.showLocation ?? (!props.compact && !props.timeLabel && durationHours() >= 1.25)));\n const showDescription = () =>\n Boolean(\n props.event.description?.trim() && props.fill && !props.timeLabel && !props.event.allDay && !props.compact && durationHours() >= 1.5,\n );\n const timeLabel = () =>\n props.timeLabel ?? `${formatTime(props.event.startDate, dateConfig())} - ${formatTime(props.event.endDate, dateConfig())}`;\n const ariaLabel = () => {\n const label = props.label\n ? props.label\n : props.event.allDay\n ? props.event.title\n : props.event.endDate.getTime() <= props.event.startDate.getTime()\n ? // A deadline is a moment, not a span: it names one time.\n `${props.event.title}, ${formatTime(props.event.startDate, dateConfig())}`\n : messages().calendarEventTime({\n title: props.event.title,\n start: formatTime(props.event.startDate, dateConfig()),\n end: formatTime(props.event.endDate, dateConfig()),\n });\n return [label, props.remaining, props.event.accessibleDetail].filter(Boolean).join(\", \");\n };\n const renderedEvent = () =>\n props.owner.renderEvent?.(props.event, {\n compact: props.compact ?? false,\n fill: props.fill ?? false,\n start: props.event.startDate,\n end: props.event.endDate,\n allDay: props.event.allDay ?? false,\n durationHours: durationHours(),\n timeLabel: timeLabel(),\n leadingTime: props.leadingTime,\n remaining: props.remaining,\n checkbox: props.checkbox ?? false,\n timeline: props.timeline ?? false,\n });\n const defaultContent = (\n <>\n <Show when={props.leadingTime}>\n <span class=\"k2b-calendar-event__time\">{props.leadingTime}</span>\n </Show>\n <span class=\"k2b-calendar-event__title\">\n <Show when={props.event.display === \"marker\" && !props.checkbox}>\n <span class=\"k2b-calendar-event__marker\" aria-hidden=\"true\" />\n </Show>\n {props.event.title}\n </span>\n <Show when={showTime() || props.remaining}>\n <span class=\"k2b-calendar-event__meta\">\n <Show when={showTime()}>{timeLabel()}</Show>\n <Show when={props.remaining}>\n <span class=\"k2b-calendar-event__remaining\">{showTime() ? ` · ${props.remaining}` : props.remaining}</span>\n </Show>\n </span>\n </Show>\n <Show when={showLocation()}>\n <span class=\"k2b-calendar-event__meta\">{props.event.location}</span>\n </Show>\n <Show when={showDescription()}>\n <span class=\"k2b-calendar-event__description\">{props.event.description}</span>\n </Show>\n </>\n );\n const content = () => (\n <>\n <Show when={props.hintStart}>\n <span class=\"k2b-calendar-event__hint\" data-edge=\"start\" aria-hidden=\"true\">\n {props.hintStart}\n </span>\n </Show>\n {renderedEvent() ?? defaultContent}\n <Show when={props.hintEnd}>\n <span class=\"k2b-calendar-event__hint\" data-edge=\"end\" aria-hidden=\"true\">\n {props.hintEnd}\n </span>\n </Show>\n {props.trailing}\n </>\n );\n const isActionable = () => isInteractive() || Boolean(props.onMovePointerDown);\n let suppressClickUntil = 0;\n const onClick = (event: MouseEvent) => {\n if (performance.now() < suppressClickUntil) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n if (!props.owner.onEventActivate || props.owner.eventActivation === \"double\") return;\n event.preventDefault();\n event.stopPropagation();\n props.owner.onEventActivate(props.event);\n };\n const onDoubleClick = (event: MouseEvent) => {\n if (!props.owner.onEventActivate || props.owner.eventActivation !== \"double\") return;\n event.preventDefault();\n event.stopPropagation();\n props.owner.onEventActivate(props.event);\n };\n /** Space on an entry with a box checks it; Enter still opens the entry. */\n const onCheckKeyDown = (event: KeyboardEvent) => {\n if (event.key !== \" \" || !props.onCheck || event.altKey || event.ctrlKey || event.metaKey) return false;\n event.preventDefault();\n props.onCheck();\n return true;\n };\n const onButtonKeyDown = (event: KeyboardEvent) => {\n if (onCheckKeyDown(event) || !isInteractive() || (event.key !== \"Enter\" && event.key !== \" \")) return;\n event.preventDefault();\n props.owner.onEventActivate?.(props.event);\n };\n const onPointerDown = (event: PointerEvent) => {\n if (event.pointerType === \"touch\") return;\n if (props.onMovePointerDown) event.stopPropagation();\n props.onMovePointerDown?.(event, () => {\n suppressClickUntil = performance.now() + 400;\n });\n };\n const attributes = () => ({\n class: \"k2b-calendar-event\",\n \"data-calendar-event\": \"\",\n \"data-color\": props.event.colorHex ? undefined : color(),\n \"data-selected\": selected() ? \"true\" : undefined,\n \"data-compact\": props.compact ? \"true\" : undefined,\n \"data-fill\": props.fill ? \"true\" : undefined,\n \"data-short\": short() ? \"true\" : undefined,\n \"data-moving\": props.moving ? \"true\" : undefined,\n \"data-continues-before\": props.continuesBefore ? \"true\" : undefined,\n \"data-continues-after\": props.continuesAfter ? \"true\" : undefined,\n \"data-bar\": props.bar ? \"true\" : undefined,\n \"data-display\": props.event.display,\n \"data-stop\": props.stop?.id,\n \"data-col\": props.stop?.column,\n \"data-minute\": props.stop?.minute,\n style: style(),\n \"aria-label\": ariaLabel(),\n });\n\n return props.href ? (\n <a\n {...attributes()}\n href={props.href}\n data-interactive={isInteractive() ? \"true\" : undefined}\n data-space-item-id={props.event.dataSpaceItemId}\n tabIndex={props.tabIndex}\n draggable={props.onMovePointerDown ? false : undefined}\n onClick={onClick}\n onDblClick={onDoubleClick}\n onDragStart={props.onMovePointerDown ? (event) => event.preventDefault() : undefined}\n onPointerDown={onPointerDown}\n onKeyDown={onCheckKeyDown}\n >\n {content()}\n </a>\n ) : isActionable() ? (\n <button\n {...attributes()}\n type=\"button\"\n data-interactive=\"true\"\n tabIndex={props.tabIndex}\n onClick={onClick}\n onDblClick={onDoubleClick}\n onPointerDown={onPointerDown}\n onKeyDown={onButtonKeyDown}\n >\n {content()}\n </button>\n ) : (\n <div {...attributes()} role=\"group\" tabIndex={props.tabIndex} onKeyDown={onCheckKeyDown}>\n {content()}\n </div>\n );\n};\n\nlet measureContext: CanvasRenderingContext2D | null | undefined;\n/** The width of a text in a font, from a canvas, so a bar can tell whether its title leaves room for a date hint. */\nexport const textWidth = (text: string, font: string): number => {\n measureContext ??= typeof document === \"undefined\" ? null : document.createElement(\"canvas\").getContext(\"2d\");\n if (!measureContext) return Number.POSITIVE_INFINITY;\n measureContext.font = font;\n return measureContext.measureText(text).width;\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/calendar-shared.tsx"],"sourcesContent":["import { dates as calendar, type DateContext } from \"@k2b/stdlib\";\nimport type { JSX } from \"solid-js\";\nimport { createMemo, Show } from \"solid-js\";\nimport { AvatarFaces } from \"../surfaces/AvatarStack\";\nimport type { CalendarEvent, CalendarProps } from \"./Calendar\";\nimport { useCalendarMessages } from \"./calendar-messages\";\n\n/** One piece of an event in one day, with the times of the whole event. */\nexport type NormalizedEvent = CalendarEvent & {\n startDate: Date;\n endDate: Date;\n dayKey: string;\n sourceStartDate: Date;\n sourceEndDate: Date;\n};\n\n/** A keyboard stop of the week grid. */\nexport type CalendarStop = { id: string; column: number; minute: number };\n\n/** What the built-in views read from the props: they only ever link to built-in views. */\nexport type CalendarOwner = Omit<CalendarProps, \"view\" | \"customViews\" | \"children\"> & {\n /** The calendar's clock, which ticks every minute; an open entry in the past is overdue. */\n calendarNow?: () => Date;\n /** Without `onEventActivate`: opens the calendar's own detail of an entry beside the element that opened it. */\n openEventDetail?: (event: CalendarEvent, anchor: HTMLElement) => void;\n};\n\n/** `data` keys the calendar writes as `data-*` attributes: camelCase letters and digits, none of the calendar's own. */\nconst DATA_KEY = /^[a-z][a-zA-Z0-9]*$/;\nexport const eventDataAttributes = (data: CalendarEvent[\"data\"]): Record<string, string> => {\n const attributes: Record<string, string> = {};\n for (const [key, value] of Object.entries(data ?? {})) {\n if (!DATA_KEY.test(key) || key.startsWith(\"calendar\") || typeof value !== \"string\") continue;\n attributes[`data-${key.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)}`] = value;\n }\n return attributes;\n};\n\n/** An open to-do or deadline whose time has passed. */\nexport const isOverdue = (event: CalendarEvent & { sourceStartDate?: Date; sourceEndDate?: Date }, now: Date | undefined): boolean => {\n if (event.checked !== false || !now) return false;\n const start = event.sourceStartDate?.getTime() ?? Number.NaN;\n const end = event.sourceEndDate?.getTime() ?? start;\n return Math.max(start, end) <= now.getTime();\n};\n\nexport const ownerDateConfig = (owner: CalendarOwner): DateContext => ({\n ...owner.dateConfig,\n timeZone: owner.timeZone ?? owner.dateConfig?.timeZone,\n firstDayOfWeek: owner.firstDayOfWeek ?? owner.dateConfig?.firstDayOfWeek ?? owner.dateConfig?.weekStartsOn ?? 1,\n});\n\nconst dateOnlyPattern = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nexport const parseDate = (value: Date | string, context?: DateContext): Date => {\n if (value instanceof Date) return new Date(value);\n if (dateOnlyPattern.test(value)) return calendar.parseCalendarDate(value, context);\n const normalized = value.includes(\"T\") ? value : value.replace(\" \", \"T\");\n const parsed = new Date(normalized);\n if (!Number.isNaN(parsed.getTime())) return parsed;\n const [year, month = \"1\", day = \"1\"] = value.split(\"-\");\n return new Date(Number(year), Number(month) - 1, Number(day), 12);\n};\n\nexport const validDate = (value: Date): boolean => !Number.isNaN(value.getTime());\n\nexport const formatTime = (date: Date, context?: DateContext): string => calendar.formatTime(date, context);\n\nexport const eventHref = (props: CalendarOwner, event: CalendarEvent): string | undefined => props.getEventHref?.(event) ?? event.href;\n\n/** Places a calendar popover below its anchor when there is room and above it otherwise, inside the viewport. */\nexport const placeCalendarPopover = (anchor: Element | DOMRect, popover: HTMLElement): void => {\n const margin = 8;\n const gap = 4;\n const rect = anchor instanceof Element ? anchor.getBoundingClientRect() : anchor;\n const width = Math.min(popover.offsetWidth || 288, window.innerWidth - margin * 2);\n const height = popover.offsetHeight;\n const left = Math.max(margin, Math.min(rect.left, window.innerWidth - width - margin));\n const roomBelow = window.innerHeight - rect.bottom - gap - margin;\n const above = height > roomBelow && rect.top - gap - margin > roomBelow;\n const top = above ? Math.max(margin, rect.top - height - gap) : Math.min(rect.bottom + gap, window.innerHeight - height - margin);\n popover.style.left = `${left}px`;\n popover.style.top = `${Math.max(margin, top)}px`;\n};\n\n/** Follows a calendar link the way the calendar's own links do: through the host's navigation when it has one. */\nexport const followCalendarHref = (owner: CalendarOwner, href: string): void => {\n if (owner.onNavigateHref) owner.onNavigateHref(href);\n else window.location.assign(href);\n};\n\nexport const EventChip = (props: {\n event: NormalizedEvent;\n owner: CalendarOwner;\n href?: string;\n compact?: boolean;\n fill?: boolean;\n moving?: boolean;\n /** Replaces the title and time at the start of the accessible name, for example with the dates a long event spans. */\n label?: string;\n /** A bar of a long event that goes on before or after the week row it sits in. */\n continuesBefore?: boolean;\n continuesAfter?: boolean;\n /** Month view: an all-day or multi-day entry drawn as a bar. */\n bar?: boolean;\n /** Short dates at the torn ends of a bar, where it continues in another week row. */\n hintStart?: string;\n hintEnd?: string;\n /** Month view: the start time before the title. */\n leadingTime?: string;\n /** Day and week views: what is left of a running event, such as \"27 min left\". */\n remaining?: string;\n /** Day and week views: the calendar draws the event's checkbox beside the chip. */\n checkbox?: boolean;\n /** Day and week views with `dayHours`: the chip is a band, a deadline, or an all-day entry of a timeline. */\n timeline?: boolean;\n /** Text after the content, such as the time of a deadline. */\n trailing?: JSX.Element;\n /** Day and week views: the time as they write it, such as \"10:30–11:15\", shown whatever the length. */\n timeLabel?: string;\n /** Day view: a band tall enough shows its place below the time. */\n showLocation?: boolean;\n /** Week view: the grid's one tab stop decides which chip takes Tab. */\n tabIndex?: number;\n /** A keyboard stop of the week grid: its id, its day column, and its minute for moving between columns. */\n stop?: CalendarStop;\n /** Day and week views: Space on the chip checks the box the calendar draws beside it, as on the box itself. */\n onCheck?: () => void;\n onMovePointerDown?: (event: PointerEvent, onActivate: () => void) => void;\n /** How many faces of the attendees fit: up to three in a band, one in the day list, none by default. */\n faces?: number;\n /** Shows how many links the entry has, where there is room beside the title or time. */\n linkCount?: boolean;\n}): JSX.Element => {\n const messages = useCalendarMessages();\n const dateConfig = createMemo(() => ownerDateConfig(props.owner));\n const color = () => props.event.color ?? \"blue\";\n const selected = () => Boolean(props.owner.selectedEventId) && props.owner.selectedEventId === props.event.id;\n const style = () => (props.event.colorHex ? { \"--k2b-calendar-accent\": props.event.colorHex } : undefined);\n const activate = (anchor: HTMLElement) => {\n if (props.owner.onEventActivate) props.owner.onEventActivate(props.event);\n else props.owner.openEventDetail?.(props.event, anchor);\n };\n const isInteractive = () => Boolean(props.owner.onEventActivate ?? props.owner.openEventDetail);\n const done = () => props.event.checked === true;\n const overdue = () => isOverdue(props.event, props.owner.calendarNow?.());\n const attendees = () => props.event.attendees ?? [];\n const links = () => props.event.links ?? [];\n const shownFaces = () => (props.faces ? attendees().slice(0, props.faces) : []);\n const durationHours = () => (props.event.endDate.getTime() - props.event.startDate.getTime()) / 3_600_000;\n const short = () => Boolean(props.fill && !props.event.allDay && durationHours() < 0.75);\n const showTime = () => (props.timeLabel ? !props.event.allDay : !props.event.allDay && !props.compact && durationHours() >= 0.75);\n const showLocation = () =>\n Boolean(props.event.location && (props.showLocation ?? (!props.compact && !props.timeLabel && durationHours() >= 1.25)));\n const showDescription = () =>\n Boolean(\n props.event.description?.trim() && props.fill && !props.timeLabel && !props.event.allDay && !props.compact && durationHours() >= 1.5,\n );\n const timeLabel = () =>\n props.timeLabel ?? `${formatTime(props.event.startDate, dateConfig())} - ${formatTime(props.event.endDate, dateConfig())}`;\n const ariaLabel = () => {\n const label = props.label\n ? props.label\n : props.event.allDay\n ? props.event.title\n : props.event.endDate.getTime() <= props.event.startDate.getTime()\n ? // A deadline is a moment, not a span: it names one time.\n `${props.event.title}, ${formatTime(props.event.startDate, dateConfig())}`\n : messages().calendarEventTime({\n title: props.event.title,\n start: formatTime(props.event.startDate, dateConfig()),\n end: formatTime(props.event.endDate, dateConfig()),\n });\n return [\n label,\n props.remaining,\n done() ? messages().calendarStateDone : overdue() ? messages().calendarStateOverdue : undefined,\n attendees().length ? messages().calendarPeopleCount({ count: attendees().length }) : undefined,\n links().length ? messages().calendarLinkCount({ count: links().length }) : undefined,\n props.event.accessibleDetail,\n ]\n .filter(Boolean)\n .join(\", \");\n };\n const renderedEvent = () =>\n props.owner.renderEvent?.(props.event, {\n compact: props.compact ?? false,\n fill: props.fill ?? false,\n start: props.event.startDate,\n end: props.event.endDate,\n allDay: props.event.allDay ?? false,\n durationHours: durationHours(),\n timeLabel: timeLabel(),\n leadingTime: props.leadingTime,\n remaining: props.remaining,\n checkbox: props.checkbox ?? false,\n timeline: props.timeline ?? false,\n });\n // Faces and the link count only take room the title and time leave; they carry no text of their own.\n const icon = () => (props.event.icon ? <i class={`k2b-calendar-event__icon ${props.event.icon}`} aria-hidden=\"true\" /> : undefined);\n const metaText = () => (\n <>\n <Show when={showTime()}>{timeLabel()}</Show>\n <Show when={props.remaining}>\n <span class=\"k2b-calendar-event__remaining\">{showTime() ? ` · ${props.remaining}` : props.remaining}</span>\n </Show>\n </>\n );\n const hasExtras = () => shownFaces().length > 0 || Boolean(props.linkCount && links().length > 0);\n const extras = () =>\n hasExtras() ? (\n <span class=\"k2b-calendar-event__extras\" aria-hidden=\"true\">\n <Show when={shownFaces().length > 0}>\n <AvatarFaces people={shownFaces()} total={(props.faces ?? 0) > 1 ? attendees().length : undefined} max={props.faces} />\n </Show>\n <Show when={props.linkCount && links().length > 0}>\n <span class=\"k2b-calendar-event__links\">\n <i class=\"ti ti-link\" />\n {links().length}\n </span>\n </Show>\n </span>\n ) : undefined;\n const defaultContent = (\n <>\n {/* The icon leads the entry: before the month view's start time, else inside the title, which a band wraps. */}\n <Show when={props.leadingTime}>\n {icon()}\n <span class=\"k2b-calendar-event__time\">{props.leadingTime}</span>\n </Show>\n <span class=\"k2b-calendar-event__title\">\n <Show when={!props.leadingTime}>{icon()}</Show>\n {props.event.title}\n </span>\n <Show\n when={hasExtras()}\n fallback={\n <Show when={showTime() || props.remaining}>\n <span class=\"k2b-calendar-event__meta\">{metaText()}</span>\n </Show>\n }\n >\n <span class=\"k2b-calendar-event__row\">\n <Show when={showTime() || props.remaining}>\n <span class=\"k2b-calendar-event__meta\">{metaText()}</span>\n </Show>\n {extras()}\n </span>\n </Show>\n <Show when={showLocation()}>\n <span class=\"k2b-calendar-event__meta\">{props.event.location}</span>\n </Show>\n <Show when={showDescription()}>\n <span class=\"k2b-calendar-event__description\">{props.event.description}</span>\n </Show>\n </>\n );\n const content = () => (\n <>\n <Show when={props.hintStart}>\n <span class=\"k2b-calendar-event__hint\" data-edge=\"start\" aria-hidden=\"true\">\n {props.hintStart}\n </span>\n </Show>\n {renderedEvent() ?? defaultContent}\n <Show when={props.hintEnd}>\n <span class=\"k2b-calendar-event__hint\" data-edge=\"end\" aria-hidden=\"true\">\n {props.hintEnd}\n </span>\n </Show>\n {props.trailing}\n </>\n );\n const isActionable = () => isInteractive() || Boolean(props.onMovePointerDown);\n let suppressClickUntil = 0;\n const onClick = (event: MouseEvent) => {\n if (performance.now() < suppressClickUntil) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n if (!isInteractive() || props.owner.eventActivation === \"double\") return;\n // A link with a modifier or another button still opens where the reader asked, such as in a new tab.\n if (props.href && (event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)) return;\n event.preventDefault();\n event.stopPropagation();\n activate(event.currentTarget as HTMLElement);\n };\n const onDoubleClick = (event: MouseEvent) => {\n if (!isInteractive() || props.owner.eventActivation !== \"double\") return;\n event.preventDefault();\n event.stopPropagation();\n activate(event.currentTarget as HTMLElement);\n };\n /** Space on an entry with a box checks it; Enter still opens the entry. */\n const onCheckKeyDown = (event: KeyboardEvent) => {\n if (event.key !== \" \" || !props.onCheck || event.altKey || event.ctrlKey || event.metaKey) return false;\n event.preventDefault();\n props.onCheck();\n return true;\n };\n const onButtonKeyDown = (event: KeyboardEvent) => {\n if (onCheckKeyDown(event) || !isInteractive() || (event.key !== \"Enter\" && event.key !== \" \")) return;\n event.preventDefault();\n activate(event.currentTarget as HTMLElement);\n };\n const onPointerDown = (event: PointerEvent) => {\n if (event.pointerType === \"touch\") return;\n if (props.onMovePointerDown) event.stopPropagation();\n props.onMovePointerDown?.(event, () => {\n suppressClickUntil = performance.now() + 400;\n });\n };\n const attributes = () => ({\n class: \"k2b-calendar-event\",\n \"data-calendar-event\": \"\",\n \"data-color\": props.event.colorHex ? undefined : color(),\n \"data-selected\": selected() ? \"true\" : undefined,\n \"data-compact\": props.compact ? \"true\" : undefined,\n \"data-fill\": props.fill ? \"true\" : undefined,\n \"data-short\": short() ? \"true\" : undefined,\n \"data-moving\": props.moving ? \"true\" : undefined,\n \"data-continues-before\": props.continuesBefore ? \"true\" : undefined,\n \"data-continues-after\": props.continuesAfter ? \"true\" : undefined,\n \"data-bar\": props.bar ? \"true\" : undefined,\n \"data-display\": props.event.display,\n \"data-done\": done() ? \"true\" : undefined,\n \"data-overdue\": overdue() ? \"true\" : undefined,\n ...eventDataAttributes(props.event.data),\n \"data-stop\": props.stop?.id,\n \"data-col\": props.stop?.column,\n \"data-minute\": props.stop?.minute,\n style: style(),\n \"aria-label\": ariaLabel(),\n });\n\n return props.href ? (\n <a\n {...attributes()}\n href={props.href}\n data-interactive={isInteractive() ? \"true\" : undefined}\n tabIndex={props.tabIndex}\n draggable={props.onMovePointerDown ? false : undefined}\n onClick={onClick}\n onDblClick={onDoubleClick}\n onDragStart={props.onMovePointerDown ? (event) => event.preventDefault() : undefined}\n onPointerDown={onPointerDown}\n onKeyDown={onCheckKeyDown}\n >\n {content()}\n </a>\n ) : isActionable() ? (\n <button\n {...attributes()}\n type=\"button\"\n data-interactive=\"true\"\n tabIndex={props.tabIndex}\n onClick={onClick}\n onDblClick={onDoubleClick}\n onPointerDown={onPointerDown}\n onKeyDown={onButtonKeyDown}\n >\n {content()}\n </button>\n ) : (\n <div {...attributes()} role=\"group\" tabIndex={props.tabIndex} onKeyDown={onCheckKeyDown}>\n {content()}\n </div>\n );\n};\n\nlet measureContext: CanvasRenderingContext2D | null | undefined;\n/** The width of a text in a font, from a canvas, so a bar can tell whether its title leaves room for a date hint. */\nexport const textWidth = (text: string, font: string): number => {\n measureContext ??= typeof document === \"undefined\" ? null : document.createElement(\"canvas\").getContext(\"2d\");\n if (!measureContext) return Number.POSITIVE_INFINITY;\n measureContext.font = font;\n return measureContext.measureText(text).width;\n};\n"],"mappings":"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","ignoreList":[]}