@squirkle-ui/calendar 0.0.0-stage → 0.1.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.
@@ -0,0 +1,651 @@
1
+ import { defineComponent, computed, ref, onMounted, onBeforeUnmount, watch, nextTick, resolveComponent, openBlock, createElementBlock, createVNode, createElementVNode, withCtx, createTextVNode, toDisplayString, Fragment, renderList, createBlock, createCommentVNode, withModifiers, normalizeClass, normalizeStyle } from "vue";
2
+ import { toISODate, weekdayNames, startOfWeek, addDays, monthGrid, isSameDay, isSameMonth, toUnit, addMonths } from "@squirkle-ui/core";
3
+ import { vModel, SqShape, SqBtnToggle, SqBtn, useProxiedModel, config, colorValue } from "@squirkle-ui/ui";
4
+ function normalizeEvent(ev) {
5
+ const start = new Date(ev.start);
6
+ const end = ev.end ? new Date(ev.end) : new Date(start.getTime() + (ev.allDay ? 864e5 : 36e5));
7
+ return { ev, start, end: end > start ? end : new Date(start.getTime() + 15 * 6e4) };
8
+ }
9
+ function layoutDay(events, day) {
10
+ const d0 = new Date(day.getFullYear(), day.getMonth(), day.getDate()).getTime();
11
+ const d1 = d0 + 864e5;
12
+ const items = events.filter((e) => !e.ev.allDay && e.start.getTime() < d1 && e.end.getTime() > d0).map((e) => ({ ...e, s: Math.max(e.start.getTime(), d0), f: Math.min(e.end.getTime(), d1) })).sort((a, b) => a.s - b.s || b.f - a.f);
13
+ const out = [];
14
+ let cluster = [];
15
+ let clusterEnd = -1;
16
+ const flush = () => {
17
+ const cols = Math.max(1, ...cluster.map((c) => c.col + 1));
18
+ for (const c of cluster) out.push({ ev: c.ev, start: c.start, end: c.end, col: c.col, cols, top: (c.s - d0) / 6e4, height: Math.max(15, (c.f - c.s) / 6e4) });
19
+ cluster = [];
20
+ };
21
+ for (const it of items) {
22
+ if (it.s >= clusterEnd && cluster.length) flush();
23
+ const used = new Set(cluster.filter((c) => c.f > it.s).map((c) => c.col));
24
+ let col = 0;
25
+ while (used.has(col)) col++;
26
+ cluster.push({ ...it, col });
27
+ clusterEnd = Math.max(clusterEnd, it.f);
28
+ }
29
+ if (cluster.length) flush();
30
+ return out;
31
+ }
32
+ const eventsOnDay = (events, day) => {
33
+ const d0 = new Date(day.getFullYear(), day.getMonth(), day.getDate()).getTime();
34
+ const d1 = d0 + 864e5;
35
+ return events.filter((e) => e.start.getTime() < d1 && e.end.getTime() > d0).sort((a, b) => Number(!!b.ev.allDay) - Number(!!a.ev.allDay) || a.start.getTime() - b.start.getTime());
36
+ };
37
+ const _sfc_main = defineComponent({
38
+ name: "SqCalendar",
39
+ components: { SqBtn, SqBtnToggle, SqShape },
40
+ model: vModel,
41
+ props: {
42
+ /** Focused date (ISO `YYYY-MM-DD`). */
43
+ modelValue: { type: String, default: void 0 },
44
+ view: { type: String, default: "month" },
45
+ views: { type: Array, default: () => ["month", "week", "day"] },
46
+ events: { type: Array, default: () => [] },
47
+ firstDayOfWeek: { type: Number, default: 0 },
48
+ editable: Boolean,
49
+ /** Minutes the drag snaps to. */
50
+ snap: { type: Number, default: 15 },
51
+ hourHeight: { type: Number, default: 48 },
52
+ height: { type: [Number, String], default: 560 },
53
+ maxEvents: { type: Number, default: 3 },
54
+ locale: { type: String, default: void 0 },
55
+ hour12: { type: Boolean, default: void 0 }
56
+ },
57
+ emits: ["update:modelValue", "update:view", "click:event", "click:date", "click:time", "event-change"],
58
+ setup(props, { emit }) {
59
+ const dateModel = useProxiedModel(props, emit, "modelValue", () => toISODate(/* @__PURE__ */ new Date()));
60
+ const viewModel = useProxiedModel(props, emit, "view");
61
+ const loc = computed(() => props.locale ?? config.locale.code);
62
+ const focus = computed(() => {
63
+ const [y, m, d] = (dateModel.value ?? toISODate(/* @__PURE__ */ new Date())).split("-").map(Number);
64
+ return new Date(y, m - 1, d);
65
+ });
66
+ const norm = computed(() => props.events.map(normalizeEvent));
67
+ const weekdays = computed(() => weekdayNames(loc.value, props.firstDayOfWeek, "short"));
68
+ const viewLabels = { month: "Month", week: "Week", day: "Day" };
69
+ const now = ref(/* @__PURE__ */ new Date());
70
+ let timer;
71
+ onMounted(() => timer = setInterval(() => now.value = /* @__PURE__ */ new Date(), 6e4));
72
+ onBeforeUnmount(() => clearInterval(timer));
73
+ const title = computed(() => {
74
+ const f = focus.value;
75
+ if (viewModel.value === "day") return new Intl.DateTimeFormat(loc.value, { dateStyle: "full" }).format(f);
76
+ if (viewModel.value === "week") {
77
+ const a = startOfWeek(f, props.firstDayOfWeek);
78
+ const b = addDays(a, 6);
79
+ const fmt = new Intl.DateTimeFormat(loc.value, { month: "short", day: "numeric" });
80
+ return `${fmt.format(a)} – ${fmt.format(b)}, ${b.getFullYear()}`;
81
+ }
82
+ return new Intl.DateTimeFormat(loc.value, { month: "long", year: "numeric" }).format(f);
83
+ });
84
+ const monthDays = computed(
85
+ () => monthGrid(focus.value, props.firstDayOfWeek).map((date) => ({ date, key: toISODate(date), inMonth: isSameMonth(date, focus.value), today: isSameDay(date, now.value), events: eventsOnDay(norm.value, date) }))
86
+ );
87
+ const columns = computed(() => {
88
+ const start = viewModel.value === "day" ? focus.value : startOfWeek(focus.value, props.firstDayOfWeek);
89
+ const count = viewModel.value === "day" ? 1 : 7;
90
+ const wfmt = new Intl.DateTimeFormat(loc.value, { weekday: "short" });
91
+ return Array.from({ length: count }, (_, i) => {
92
+ const date = addDays(start, i);
93
+ return { date, key: toISODate(date), weekday: wfmt.format(date), today: isSameDay(date, now.value), placed: layoutDay(norm.value, date), allDay: eventsOnDay(norm.value, date).filter((e) => e.ev.allDay) };
94
+ });
95
+ });
96
+ const shift = (d) => {
97
+ const f = focus.value;
98
+ dateModel.value = toISODate(viewModel.value === "month" ? addMonths(f, d) : addDays(f, d * (viewModel.value === "week" ? 7 : 1)));
99
+ };
100
+ const today = () => dateModel.value = toISODate(/* @__PURE__ */ new Date());
101
+ const goDay = (d) => {
102
+ dateModel.value = toISODate(d);
103
+ viewModel.value = "day";
104
+ };
105
+ const colorOf = (ev) => colorValue(ev.color ?? "primary");
106
+ const time = (d) => new Intl.DateTimeFormat(loc.value, { hour: "numeric", minute: "2-digit", hour12: props.hour12 }).format(d);
107
+ const hourLabel = (h) => new Intl.DateTimeFormat(loc.value, { hour: "numeric", hour12: props.hour12 }).format(new Date(2024, 0, 1, h));
108
+ const nowTop = computed(() => (now.value.getHours() * 60 + now.value.getMinutes()) / 60 * props.hourHeight);
109
+ const dragId = ref(null);
110
+ const dropKey = ref("");
111
+ const onMonthDrop = (date) => {
112
+ dropKey.value = "";
113
+ const e = norm.value.find((x) => x.ev.id === dragId.value);
114
+ dragId.value = null;
115
+ if (!e || !props.editable) return;
116
+ const delta = Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(e.start.getFullYear(), e.start.getMonth(), e.start.getDate()).getTime()) / 864e5);
117
+ if (delta) emit("event-change", { event: e.ev, start: addDays(e.start, delta), end: addDays(e.end, delta) });
118
+ };
119
+ const scroller = ref(null);
120
+ const dragState = ref(null);
121
+ const moved = ref(false);
122
+ let origin = { x: 0, y: 0, colWidth: 1, placed: null };
123
+ const snapMin = (m) => Math.round(m / props.snap) * props.snap;
124
+ const onDragMove = (e) => {
125
+ if (!dragState.value) return;
126
+ const dy = e.clientY - origin.y;
127
+ const dx = e.clientX - origin.x;
128
+ if (Math.abs(dy) + Math.abs(dx) > 4) moved.value = true;
129
+ dragState.value = { ...dragState.value, dMin: snapMin(dy / props.hourHeight * 60), dDay: dragState.value.mode === "move" ? Math.round(dx / origin.colWidth) : 0 };
130
+ };
131
+ const onDragEnd = () => {
132
+ window.removeEventListener("pointermove", onDragMove);
133
+ window.removeEventListener("pointerup", onDragEnd);
134
+ const s = dragState.value;
135
+ const p = origin.placed;
136
+ dragState.value = null;
137
+ if (!s || !p || !moved.value) return;
138
+ const start = new Date(p.start.getTime() + (s.mode === "move" ? s.dMin * 6e4 : 0) + s.dDay * 864e5);
139
+ const end = new Date(p.end.getTime() + s.dMin * 6e4 + s.dDay * 864e5);
140
+ if (end > start) emit("event-change", { event: p.ev, start, end });
141
+ setTimeout(() => moved.value = false, 0);
142
+ };
143
+ const startDrag = (e, p, mode) => {
144
+ if (!props.editable || e.button !== 0) return;
145
+ const col = e.currentTarget.closest(".sq-calendar__col");
146
+ origin = { x: e.clientX, y: e.clientY, colWidth: col?.offsetWidth || 1, placed: p };
147
+ moved.value = false;
148
+ dragState.value = { id: p.ev.id, mode, dMin: 0, dDay: 0 };
149
+ window.addEventListener("pointermove", onDragMove);
150
+ window.addEventListener("pointerup", onDragEnd);
151
+ };
152
+ onBeforeUnmount(onDragEnd);
153
+ const previewStart = (p) => dragState.value?.id === p.ev.id && dragState.value.mode === "move" ? new Date(p.start.getTime() + dragState.value.dMin * 6e4) : p.start;
154
+ const previewEnd = (p) => dragState.value?.id === p.ev.id ? new Date(p.end.getTime() + dragState.value.dMin * 6e4) : p.end;
155
+ const eventStyle = (p) => {
156
+ const ds = dragState.value?.id === p.ev.id ? dragState.value : null;
157
+ const top = (p.top + (ds && ds.mode === "move" ? ds.dMin : 0)) / 60 * props.hourHeight;
158
+ const height = Math.max(18, (p.height + (ds && ds.mode === "resize" ? ds.dMin : 0)) / 60 * props.hourHeight - 2);
159
+ return {
160
+ top: `${top}px`,
161
+ height: `${height}px`,
162
+ left: `calc(${p.col / p.cols * 100}% + 2px)`,
163
+ width: `calc(${100 / p.cols}% - 4px)`,
164
+ transform: ds && ds.dDay ? `translateX(${ds.dDay * 100}%)` : void 0,
165
+ "--sq-ev": colorOf(p.ev)
166
+ };
167
+ };
168
+ const onSlotClick = (e, date) => {
169
+ const col = e.currentTarget;
170
+ const minutes = snapMin((e.clientY - col.getBoundingClientRect().top) / props.hourHeight * 60);
171
+ emit("click:time", new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, minutes));
172
+ };
173
+ const scrollToNow = () => nextTick(() => scroller.value && (scroller.value.scrollTop = Math.max(0, nowTop.value - 120)));
174
+ onMounted(scrollToNow);
175
+ watch(viewModel, (v) => v !== "month" && scrollToNow());
176
+ return {
177
+ viewModel,
178
+ viewLabels,
179
+ weekdays,
180
+ title,
181
+ monthDays,
182
+ columns,
183
+ shift,
184
+ today,
185
+ goDay,
186
+ colorOf,
187
+ time,
188
+ hourLabel,
189
+ nowTop,
190
+ dragId,
191
+ dropKey,
192
+ onMonthDrop,
193
+ scroller,
194
+ dragState,
195
+ moved,
196
+ startDrag,
197
+ previewStart,
198
+ previewEnd,
199
+ eventStyle,
200
+ onSlotClick,
201
+ toUnit,
202
+ messages: computed(() => config.locale.messages)
203
+ };
204
+ }
205
+ });
206
+ const _export_sfc = (sfc, props) => {
207
+ const target = sfc.__vccOpts || sfc;
208
+ for (const [key, val] of props) {
209
+ target[key] = val;
210
+ }
211
+ return target;
212
+ };
213
+ const _hoisted_1 = {
214
+ class: "sq-calendar sq-surface",
215
+ style: { "--sq-r": "var(--sq-radius-xl)", "--sq-bg": "var(--sq-surface)", "--sq-bd": "var(--sq-border)", "--sq-bw": "1px" }
216
+ };
217
+ const _hoisted_2 = { class: "sq-calendar__toolbar" };
218
+ const _hoisted_3 = { class: "sq-calendar__title" };
219
+ const _hoisted_4 = {
220
+ key: 0,
221
+ class: "sq-calendar__month"
222
+ };
223
+ const _hoisted_5 = ["onClick", "onDragover", "onDragleave", "onDrop"];
224
+ const _hoisted_6 = { class: "sq-calendar__date sq-squircle" };
225
+ const _hoisted_7 = ["draggable", "title", "onDragstart", "onClick"];
226
+ const _hoisted_8 = {
227
+ key: 0,
228
+ class: "sq-calendar__chip-time"
229
+ };
230
+ const _hoisted_9 = ["onClick"];
231
+ const _hoisted_10 = { class: "sq-calendar__time-head" };
232
+ const _hoisted_11 = { class: "sq-squircle" };
233
+ const _hoisted_12 = { class: "sq-calendar__allday" };
234
+ const _hoisted_13 = ["onClick"];
235
+ const _hoisted_14 = { class: "sq-calendar__gutter sq-calendar__hours" };
236
+ const _hoisted_15 = { key: 0 };
237
+ const _hoisted_16 = ["onClick"];
238
+ const _hoisted_17 = ["onPointerdown", "onClick"];
239
+ const _hoisted_18 = { class: "sq-calendar__event-title" };
240
+ const _hoisted_19 = { class: "sq-calendar__event-time" };
241
+ const _hoisted_20 = ["onPointerdown"];
242
+ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
243
+ const _component_SqShape = resolveComponent("SqShape");
244
+ const _component_SqBtn = resolveComponent("SqBtn");
245
+ const _component_SqBtnToggle = resolveComponent("SqBtnToggle");
246
+ return openBlock(), createElementBlock("div", _hoisted_1, [
247
+ createVNode(_component_SqShape, { clip: "" }),
248
+ createElementVNode("div", _hoisted_2, [
249
+ createVNode(_component_SqBtn, {
250
+ variant: "tonal",
251
+ size: "small",
252
+ onClick: _ctx.today
253
+ }, {
254
+ default: withCtx(() => [
255
+ createTextVNode(
256
+ toDisplayString(_ctx.messages.today),
257
+ 1
258
+ /* TEXT */
259
+ )
260
+ ]),
261
+ _: 1
262
+ /* STABLE */
263
+ }, 8, ["onClick"]),
264
+ createVNode(_component_SqBtn, {
265
+ icon: "chevronLeft",
266
+ variant: "text",
267
+ color: "surface",
268
+ size: "small",
269
+ "aria-label": _ctx.messages.previous,
270
+ onClick: _cache[0] || (_cache[0] = ($event) => _ctx.shift(-1))
271
+ }, null, 8, ["aria-label"]),
272
+ createVNode(_component_SqBtn, {
273
+ icon: "chevronRight",
274
+ variant: "text",
275
+ color: "surface",
276
+ size: "small",
277
+ "aria-label": _ctx.messages.next,
278
+ onClick: _cache[1] || (_cache[1] = ($event) => _ctx.shift(1))
279
+ }, null, 8, ["aria-label"]),
280
+ createElementVNode(
281
+ "div",
282
+ _hoisted_3,
283
+ toDisplayString(_ctx.title),
284
+ 1
285
+ /* TEXT */
286
+ ),
287
+ _cache[3] || (_cache[3] = createElementVNode(
288
+ "span",
289
+ { class: "sq-spacer" },
290
+ null,
291
+ -1
292
+ /* CACHED */
293
+ )),
294
+ createVNode(_component_SqBtnToggle, {
295
+ modelValue: _ctx.viewModel,
296
+ "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => _ctx.viewModel = $event),
297
+ mandatory: ""
298
+ }, {
299
+ default: withCtx(() => [
300
+ (openBlock(true), createElementBlock(
301
+ Fragment,
302
+ null,
303
+ renderList(_ctx.views, (v) => {
304
+ return openBlock(), createBlock(_component_SqBtn, {
305
+ key: v,
306
+ value: v,
307
+ size: "small",
308
+ variant: "text",
309
+ color: "surface"
310
+ }, {
311
+ default: withCtx(() => [
312
+ createTextVNode(
313
+ toDisplayString(_ctx.viewLabels[v]),
314
+ 1
315
+ /* TEXT */
316
+ )
317
+ ]),
318
+ _: 2
319
+ /* DYNAMIC */
320
+ }, 1032, ["value"]);
321
+ }),
322
+ 128
323
+ /* KEYED_FRAGMENT */
324
+ ))
325
+ ]),
326
+ _: 1
327
+ /* STABLE */
328
+ }, 8, ["modelValue"])
329
+ ]),
330
+ createCommentVNode(" month "),
331
+ _ctx.viewModel === "month" ? (openBlock(), createElementBlock("div", _hoisted_4, [
332
+ (openBlock(true), createElementBlock(
333
+ Fragment,
334
+ null,
335
+ renderList(_ctx.weekdays, (w, wi) => {
336
+ return openBlock(), createElementBlock(
337
+ "div",
338
+ {
339
+ key: wi,
340
+ class: "sq-calendar__weekday"
341
+ },
342
+ toDisplayString(w),
343
+ 1
344
+ /* TEXT */
345
+ );
346
+ }),
347
+ 128
348
+ /* KEYED_FRAGMENT */
349
+ )),
350
+ (openBlock(true), createElementBlock(
351
+ Fragment,
352
+ null,
353
+ renderList(_ctx.monthDays, (d) => {
354
+ return openBlock(), createElementBlock("div", {
355
+ key: d.key,
356
+ class: normalizeClass(["sq-calendar__day", { "sq-calendar__day--outside": !d.inMonth, "sq-calendar__day--today": d.today, "sq-calendar__day--drop": _ctx.dropKey === d.key }]),
357
+ onClick: ($event) => _ctx.$emit("click:date", d.key),
358
+ onDragover: withModifiers(($event) => _ctx.dropKey = d.key, ["prevent"]),
359
+ onDragleave: ($event) => _ctx.dropKey === d.key && (_ctx.dropKey = ""),
360
+ onDrop: withModifiers(($event) => _ctx.onMonthDrop(d.date), ["prevent"])
361
+ }, [
362
+ createElementVNode(
363
+ "span",
364
+ _hoisted_6,
365
+ toDisplayString(d.date.getDate()),
366
+ 1
367
+ /* TEXT */
368
+ ),
369
+ (openBlock(true), createElementBlock(
370
+ Fragment,
371
+ null,
372
+ renderList(d.events.slice(0, _ctx.maxEvents), (e) => {
373
+ return openBlock(), createElementBlock("div", {
374
+ key: String(e.ev.id),
375
+ class: normalizeClass(["sq-calendar__chip sq-squircle", { "sq-calendar__chip--allday": e.ev.allDay }]),
376
+ style: normalizeStyle({ "--sq-ev": _ctx.colorOf(e.ev) }),
377
+ draggable: _ctx.editable,
378
+ title: e.ev.title,
379
+ onDragstart: ($event) => _ctx.dragId = e.ev.id,
380
+ onClick: withModifiers(($event) => _ctx.$emit("click:event", e.ev), ["stop"])
381
+ }, [
382
+ !e.ev.allDay ? (openBlock(), createElementBlock(
383
+ "span",
384
+ _hoisted_8,
385
+ toDisplayString(_ctx.time(e.start)),
386
+ 1
387
+ /* TEXT */
388
+ )) : createCommentVNode("v-if", true),
389
+ createTextVNode(
390
+ toDisplayString(e.ev.title),
391
+ 1
392
+ /* TEXT */
393
+ )
394
+ ], 46, _hoisted_7);
395
+ }),
396
+ 128
397
+ /* KEYED_FRAGMENT */
398
+ )),
399
+ d.events.length > _ctx.maxEvents ? (openBlock(), createElementBlock("button", {
400
+ key: 0,
401
+ type: "button",
402
+ class: "sq-calendar__more",
403
+ onClick: withModifiers(($event) => _ctx.goDay(d.date), ["stop"])
404
+ }, "+" + toDisplayString(d.events.length - _ctx.maxEvents) + " more", 9, _hoisted_9)) : createCommentVNode("v-if", true)
405
+ ], 42, _hoisted_5);
406
+ }),
407
+ 128
408
+ /* KEYED_FRAGMENT */
409
+ ))
410
+ ])) : (openBlock(), createElementBlock(
411
+ Fragment,
412
+ { key: 1 },
413
+ [
414
+ createCommentVNode(" week / day "),
415
+ createElementVNode(
416
+ "div",
417
+ {
418
+ class: "sq-calendar__time",
419
+ style: normalizeStyle({ "--sq-cal-cols": _ctx.columns.length })
420
+ },
421
+ [
422
+ createElementVNode("div", _hoisted_10, [
423
+ _cache[4] || (_cache[4] = createElementVNode(
424
+ "div",
425
+ { class: "sq-calendar__gutter" },
426
+ null,
427
+ -1
428
+ /* CACHED */
429
+ )),
430
+ (openBlock(true), createElementBlock(
431
+ Fragment,
432
+ null,
433
+ renderList(_ctx.columns, (c) => {
434
+ return openBlock(), createElementBlock(
435
+ "div",
436
+ {
437
+ key: c.key,
438
+ class: normalizeClass(["sq-calendar__col-head", { "sq-calendar__col-head--today": c.today }])
439
+ },
440
+ [
441
+ createElementVNode(
442
+ "span",
443
+ null,
444
+ toDisplayString(c.weekday),
445
+ 1
446
+ /* TEXT */
447
+ ),
448
+ createElementVNode(
449
+ "b",
450
+ _hoisted_11,
451
+ toDisplayString(c.date.getDate()),
452
+ 1
453
+ /* TEXT */
454
+ )
455
+ ],
456
+ 2
457
+ /* CLASS */
458
+ );
459
+ }),
460
+ 128
461
+ /* KEYED_FRAGMENT */
462
+ ))
463
+ ]),
464
+ createElementVNode("div", _hoisted_12, [
465
+ _cache[5] || (_cache[5] = createElementVNode(
466
+ "div",
467
+ { class: "sq-calendar__gutter" },
468
+ "all-day",
469
+ -1
470
+ /* CACHED */
471
+ )),
472
+ (openBlock(true), createElementBlock(
473
+ Fragment,
474
+ null,
475
+ renderList(_ctx.columns, (c) => {
476
+ return openBlock(), createElementBlock("div", {
477
+ key: c.key,
478
+ class: "sq-calendar__allday-col"
479
+ }, [
480
+ (openBlock(true), createElementBlock(
481
+ Fragment,
482
+ null,
483
+ renderList(c.allDay, (e) => {
484
+ return openBlock(), createElementBlock("div", {
485
+ key: String(e.ev.id),
486
+ class: "sq-calendar__chip sq-calendar__chip--allday sq-squircle",
487
+ style: normalizeStyle({ "--sq-ev": _ctx.colorOf(e.ev) }),
488
+ onClick: ($event) => _ctx.$emit("click:event", e.ev)
489
+ }, toDisplayString(e.ev.title), 13, _hoisted_13);
490
+ }),
491
+ 128
492
+ /* KEYED_FRAGMENT */
493
+ ))
494
+ ]);
495
+ }),
496
+ 128
497
+ /* KEYED_FRAGMENT */
498
+ ))
499
+ ]),
500
+ createElementVNode(
501
+ "div",
502
+ {
503
+ ref: "scroller",
504
+ class: "sq-calendar__scroll",
505
+ style: normalizeStyle({ height: _ctx.toUnit(_ctx.height) })
506
+ },
507
+ [
508
+ createElementVNode(
509
+ "div",
510
+ {
511
+ class: "sq-calendar__grid",
512
+ style: normalizeStyle({ height: 24 * _ctx.hourHeight + "px" })
513
+ },
514
+ [
515
+ createElementVNode("div", _hoisted_14, [
516
+ (openBlock(), createElementBlock(
517
+ Fragment,
518
+ null,
519
+ renderList(24, (h) => {
520
+ return createElementVNode(
521
+ "div",
522
+ {
523
+ key: h,
524
+ class: "sq-calendar__hour",
525
+ style: normalizeStyle({ height: _ctx.hourHeight + "px" })
526
+ },
527
+ [
528
+ h > 1 ? (openBlock(), createElementBlock(
529
+ "span",
530
+ _hoisted_15,
531
+ toDisplayString(_ctx.hourLabel(h - 1)),
532
+ 1
533
+ /* TEXT */
534
+ )) : createCommentVNode("v-if", true)
535
+ ],
536
+ 4
537
+ /* STYLE */
538
+ );
539
+ }),
540
+ 64
541
+ /* STABLE_FRAGMENT */
542
+ ))
543
+ ]),
544
+ (openBlock(true), createElementBlock(
545
+ Fragment,
546
+ null,
547
+ renderList(_ctx.columns, (c) => {
548
+ return openBlock(), createElementBlock("div", {
549
+ key: c.key,
550
+ class: "sq-calendar__col",
551
+ onClick: ($event) => _ctx.onSlotClick($event, c.date)
552
+ }, [
553
+ (openBlock(), createElementBlock(
554
+ Fragment,
555
+ null,
556
+ renderList(24, (h) => {
557
+ return createElementVNode(
558
+ "div",
559
+ {
560
+ key: h,
561
+ class: "sq-calendar__slot",
562
+ style: normalizeStyle({ height: _ctx.hourHeight + "px" })
563
+ },
564
+ null,
565
+ 4
566
+ /* STYLE */
567
+ );
568
+ }),
569
+ 64
570
+ /* STABLE_FRAGMENT */
571
+ )),
572
+ c.today ? (openBlock(), createElementBlock(
573
+ "div",
574
+ {
575
+ key: 0,
576
+ class: "sq-calendar__now",
577
+ style: normalizeStyle({ top: _ctx.nowTop + "px" })
578
+ },
579
+ null,
580
+ 4
581
+ /* STYLE */
582
+ )) : createCommentVNode("v-if", true),
583
+ (openBlock(true), createElementBlock(
584
+ Fragment,
585
+ null,
586
+ renderList(c.placed, (p) => {
587
+ return openBlock(), createElementBlock("div", {
588
+ key: String(p.ev.id),
589
+ class: normalizeClass(["sq-calendar__event sq-squircle", { "sq-calendar__event--dragging": _ctx.dragState && _ctx.dragState.id === p.ev.id }]),
590
+ style: normalizeStyle(_ctx.eventStyle(p)),
591
+ onPointerdown: withModifiers(($event) => _ctx.startDrag($event, p, "move"), ["stop"]),
592
+ onClick: withModifiers(($event) => !_ctx.moved && _ctx.$emit("click:event", p.ev), ["stop"])
593
+ }, [
594
+ createElementVNode(
595
+ "div",
596
+ _hoisted_18,
597
+ toDisplayString(p.ev.title),
598
+ 1
599
+ /* TEXT */
600
+ ),
601
+ createElementVNode(
602
+ "div",
603
+ _hoisted_19,
604
+ toDisplayString(_ctx.time(_ctx.previewStart(p))) + " – " + toDisplayString(_ctx.time(_ctx.previewEnd(p))),
605
+ 1
606
+ /* TEXT */
607
+ ),
608
+ _ctx.editable ? (openBlock(), createElementBlock("div", {
609
+ key: 0,
610
+ class: "sq-calendar__resize",
611
+ onPointerdown: withModifiers(($event) => _ctx.startDrag($event, p, "resize"), ["stop"])
612
+ }, null, 40, _hoisted_20)) : createCommentVNode("v-if", true)
613
+ ], 46, _hoisted_17);
614
+ }),
615
+ 128
616
+ /* KEYED_FRAGMENT */
617
+ ))
618
+ ], 8, _hoisted_16);
619
+ }),
620
+ 128
621
+ /* KEYED_FRAGMENT */
622
+ ))
623
+ ],
624
+ 4
625
+ /* STYLE */
626
+ )
627
+ ],
628
+ 4
629
+ /* STYLE */
630
+ )
631
+ ],
632
+ 4
633
+ /* STYLE */
634
+ )
635
+ ],
636
+ 2112
637
+ /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
638
+ ))
639
+ ]);
640
+ }
641
+ const SqCalendar = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
642
+ const componentNames = ["SqCalendar"];
643
+ export {
644
+ SqCalendar,
645
+ componentNames,
646
+ SqCalendar as default,
647
+ eventsOnDay,
648
+ layoutDay,
649
+ normalizeEvent
650
+ };
651
+ //# sourceMappingURL=index.mjs.map