@squirkle-ui/calendar 0.0.0-stage → 0.1.1

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