@svar-ui/svelte-calendar 2.6.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 (82) hide show
  1. package/dist/Demo.svelte +7 -0
  2. package/dist/Demo.svelte.d.ts +26 -0
  3. package/dist/components/AddEventButton.svelte +12 -0
  4. package/dist/components/AddEventButton.svelte.d.ts +18 -0
  5. package/dist/components/Calendar.svelte +110 -0
  6. package/dist/components/Calendar.svelte.d.ts +153 -0
  7. package/dist/components/CalendarPanel.svelte +147 -0
  8. package/dist/components/CalendarPanel.svelte.d.ts +18 -0
  9. package/dist/components/ContextMenu.svelte +87 -0
  10. package/dist/components/ContextMenu.svelte.d.ts +17 -0
  11. package/dist/components/DateLabel.svelte +13 -0
  12. package/dist/components/DateLabel.svelte.d.ts +18 -0
  13. package/dist/components/DateNav.svelte +31 -0
  14. package/dist/components/DateNav.svelte.d.ts +18 -0
  15. package/dist/components/DateTimePicker.svelte +30 -0
  16. package/dist/components/DateTimePicker.svelte.d.ts +8 -0
  17. package/dist/components/Editor.svelte +123 -0
  18. package/dist/components/Editor.svelte.d.ts +10 -0
  19. package/dist/components/Layout.svelte +76 -0
  20. package/dist/components/Layout.svelte.d.ts +21 -0
  21. package/dist/components/MenuButton.svelte +9 -0
  22. package/dist/components/MenuButton.svelte.d.ts +18 -0
  23. package/dist/components/Navigation.svelte +59 -0
  24. package/dist/components/Navigation.svelte.d.ts +12 -0
  25. package/dist/components/Render/BarSection.svelte +89 -0
  26. package/dist/components/Render/BarSection.svelte.d.ts +13 -0
  27. package/dist/components/Render/BoxSection.svelte +94 -0
  28. package/dist/components/Render/BoxSection.svelte.d.ts +15 -0
  29. package/dist/components/Render/Grid.svelte +16 -0
  30. package/dist/components/Render/Grid.svelte.d.ts +14 -0
  31. package/dist/components/Render/GridCells.svelte +98 -0
  32. package/dist/components/Render/GridCells.svelte.d.ts +14 -0
  33. package/dist/components/Render/GridLines.svelte +45 -0
  34. package/dist/components/Render/GridLines.svelte.d.ts +10 -0
  35. package/dist/components/Render/GridSection.svelte +348 -0
  36. package/dist/components/Render/GridSection.svelte.d.ts +16 -0
  37. package/dist/components/Render/Headers.svelte +86 -0
  38. package/dist/components/Render/Headers.svelte.d.ts +8 -0
  39. package/dist/components/Render/ListSection.svelte +110 -0
  40. package/dist/components/Render/ListSection.svelte.d.ts +8 -0
  41. package/dist/components/Render/NowLine.svelte +68 -0
  42. package/dist/components/Render/NowLine.svelte.d.ts +8 -0
  43. package/dist/components/Render/ScrollableSection.svelte +207 -0
  44. package/dist/components/Render/ScrollableSection.svelte.d.ts +14 -0
  45. package/dist/components/Render/SectionContent.svelte +83 -0
  46. package/dist/components/Render/SectionContent.svelte.d.ts +17 -0
  47. package/dist/components/Render/Sections.svelte +340 -0
  48. package/dist/components/Render/Sections.svelte.d.ts +14 -0
  49. package/dist/components/Render/YearSection.svelte +265 -0
  50. package/dist/components/Render/YearSection.svelte.d.ts +9 -0
  51. package/dist/components/Render/useEventOverlay.svelte.d.ts +21 -0
  52. package/dist/components/Render/useEventOverlay.svelte.js +60 -0
  53. package/dist/components/TodayButton.svelte +11 -0
  54. package/dist/components/TodayButton.svelte.d.ts +18 -0
  55. package/dist/components/editorItems.d.ts +15 -0
  56. package/dist/components/editorItems.js +20 -0
  57. package/dist/components/types.d.ts +29 -0
  58. package/dist/components/types.js +1 -0
  59. package/dist/directives/clickdate.d.ts +8 -0
  60. package/dist/directives/clickdate.js +45 -0
  61. package/dist/directives/clickevent.d.ts +15 -0
  62. package/dist/directives/clickevent.js +54 -0
  63. package/dist/directives/drag.d.ts +19 -0
  64. package/dist/directives/drag.js +494 -0
  65. package/dist/directives/dragresize.d.ts +10 -0
  66. package/dist/directives/dragresize.js +58 -0
  67. package/dist/directives/resize.d.ts +5 -0
  68. package/dist/directives/resize.js +11 -0
  69. package/dist/dom.d.ts +1 -0
  70. package/dist/dom.js +12 -0
  71. package/dist/env.d.ts +9 -0
  72. package/dist/index.d.ts +14 -0
  73. package/dist/index.js +12 -0
  74. package/dist/init.d.ts +1 -0
  75. package/dist/init.js +5 -0
  76. package/dist/themes/Willow.svelte +16 -0
  77. package/dist/themes/Willow.svelte.d.ts +7 -0
  78. package/dist/themes/WillowDark.svelte +16 -0
  79. package/dist/themes/WillowDark.svelte.d.ts +7 -0
  80. package/license.txt +21 -0
  81. package/package.json +60 -0
  82. package/readme.md +107 -0
@@ -0,0 +1,494 @@
1
+ import { startResize } from "./dragresize.js";
2
+ import { getID } from "@svar-ui/lib-dom";
3
+ const MOVE_THRESHOLD = 3;
4
+ const CREATE_THRESHOLD = 5;
5
+ export function drag(node, options) {
6
+ let opts = options;
7
+ // ---- shared ----
8
+ function findContainingUnit(pos100, units) {
9
+ for (let i = units.length - 1; i >= 0; i--) {
10
+ if (pos100 >= units[i].position - 0.001)
11
+ return i;
12
+ }
13
+ return 0;
14
+ }
15
+ function clamp(value, min, max) {
16
+ return Math.max(min, Math.min(max, value));
17
+ }
18
+ // ---- move state ----
19
+ let moveEl = null;
20
+ let moveOrigStyle = "";
21
+ let movePending = false;
22
+ let moveActive = false;
23
+ let moveStartX = 0;
24
+ let moveStartY = 0;
25
+ let offsetX = 0;
26
+ let offsetY = 0;
27
+ let origLeft = 0;
28
+ let origTop = 0;
29
+ let offsetInUnitX = 0;
30
+ let offsetInUnitY = 0;
31
+ let moveXUnits = [];
32
+ let moveYUnits = [];
33
+ let grabXIdx = 0;
34
+ let grabYIdx = 0;
35
+ // ---- create state ----
36
+ let createPending = false;
37
+ let createActive = false;
38
+ let stub = null;
39
+ let createStartX = 0;
40
+ let createStartY = 0;
41
+ let createXUnits = [];
42
+ let createYUnits = [];
43
+ let anchorXIdx = 0;
44
+ let anchorYIdx = 0;
45
+ let anchorX = 0;
46
+ let anchorY = 0;
47
+ let anchorXIdx2 = 0;
48
+ let anchorYIdx2 = 0;
49
+ // ---- mousedown router ----
50
+ function handleMouseDown(e) {
51
+ if (e.button !== 0)
52
+ return;
53
+ const target = e.target;
54
+ const eventEl = target.closest("[data-id]");
55
+ if (eventEl && opts.move) {
56
+ startMove(e, eventEl);
57
+ }
58
+ else if (!eventEl && opts.create) {
59
+ startCreate(e);
60
+ }
61
+ }
62
+ // ---- move ----
63
+ function startMove(e, el) {
64
+ e.preventDefault();
65
+ e.stopPropagation();
66
+ moveEl = el;
67
+ moveOrigStyle = el.style.cssText;
68
+ movePending = true;
69
+ moveActive = false;
70
+ moveStartX = e.clientX;
71
+ moveStartY = e.clientY;
72
+ origLeft = parseFloat(moveEl.style.left) || 0;
73
+ origTop = parseFloat(moveEl.style.top) || 0;
74
+ const elRect = moveEl.getBoundingClientRect();
75
+ offsetX = e.clientX - elRect.left;
76
+ offsetY = e.clientY - elRect.top;
77
+ if (opts.mode === "boxes" &&
78
+ elRect.height > 40 &&
79
+ offsetY > elRect.height - 20) {
80
+ const id = getID(moveEl);
81
+ moveEl = null;
82
+ movePending = false;
83
+ if (!id)
84
+ return;
85
+ startResize(node, el, e, id, {
86
+ dx: opts.dx,
87
+ dy: opts.dy,
88
+ sectionName: opts.sectionName,
89
+ model: opts.model,
90
+ exec: opts.exec,
91
+ getEvent: opts.getEvent,
92
+ });
93
+ return;
94
+ }
95
+ moveXUnits = opts.xHeaders?.[opts.xHeaders.length - 1] ?? [];
96
+ moveYUnits = opts.yHeaders?.[opts.yHeaders.length - 1] ?? [];
97
+ if (moveXUnits.length > 0 &&
98
+ opts.dx > 0 &&
99
+ (opts.mode === "boxes" || opts.mode === "grid")) {
100
+ const posIn100 = origLeft / opts.dx;
101
+ const idx = findContainingUnit(posIn100, moveXUnits);
102
+ offsetInUnitX = origLeft - moveXUnits[idx].position * opts.dx;
103
+ }
104
+ if (moveYUnits.length > 0 &&
105
+ opts.dy > 0 &&
106
+ (opts.mode === "bars" || opts.mode === "grid")) {
107
+ const posIn100 = origTop / opts.dy;
108
+ const idx = findContainingUnit(posIn100, moveYUnits);
109
+ offsetInUnitY = origTop - moveYUnits[idx].position * opts.dy;
110
+ }
111
+ if (opts.mode === "grid" &&
112
+ moveXUnits.length > 0 &&
113
+ moveYUnits.length > 0 &&
114
+ opts.dx > 0 &&
115
+ opts.dy > 0) {
116
+ const containerRect = node.getBoundingClientRect();
117
+ const mouseX100 = (e.clientX - containerRect.left + node.scrollLeft) / opts.dx;
118
+ const mouseY100 = (e.clientY - containerRect.top + node.scrollTop) / opts.dy;
119
+ grabXIdx = findContainingUnit(mouseX100, moveXUnits);
120
+ grabYIdx = findContainingUnit(mouseY100, moveYUnits);
121
+ }
122
+ document.addEventListener("mousemove", handleMoveMouseMove);
123
+ document.addEventListener("mouseup", handleMoveMouseUp);
124
+ }
125
+ function handleMoveMouseMove(e) {
126
+ if (!moveEl || !moveEl.isConnected) {
127
+ cancelMove();
128
+ return;
129
+ }
130
+ if (movePending) {
131
+ const dx = Math.abs(e.clientX - moveStartX);
132
+ const dy = Math.abs(e.clientY - moveStartY);
133
+ if (dx < MOVE_THRESHOLD && dy < MOVE_THRESHOLD)
134
+ return;
135
+ movePending = false;
136
+ moveActive = true;
137
+ moveEl.classList.add("wx-dragging");
138
+ moveEl.style.zIndex = "100";
139
+ moveEl.style.transition = "none";
140
+ document.body.style.userSelect = "none";
141
+ }
142
+ if (!moveActive)
143
+ return;
144
+ const containerRect = node.getBoundingClientRect();
145
+ const rawX = e.clientX - containerRect.left - offsetX + node.scrollLeft;
146
+ const rawY = e.clientY - containerRect.top - offsetY + node.scrollTop;
147
+ let newLeft;
148
+ let newTop;
149
+ if (opts.mode === "boxes" && moveXUnits.length > 0 && opts.dx > 0) {
150
+ const mouseX100 = (e.clientX - containerRect.left + node.scrollLeft) / opts.dx;
151
+ const unitIdx = findContainingUnit(mouseX100, moveXUnits);
152
+ newLeft = moveXUnits[unitIdx].position * opts.dx + offsetInUnitX;
153
+ newTop = rawY;
154
+ }
155
+ else if (opts.mode === "bars") {
156
+ newLeft = rawX;
157
+ if (moveYUnits.length > 0 && opts.dy > 0) {
158
+ const mouseY100 = (e.clientY - containerRect.top + node.scrollTop) / opts.dy;
159
+ const unitIdx = findContainingUnit(mouseY100, moveYUnits);
160
+ newTop = moveYUnits[unitIdx].position * opts.dy + offsetInUnitY;
161
+ }
162
+ else {
163
+ newTop = origTop;
164
+ }
165
+ }
166
+ else if (opts.mode === "grid" &&
167
+ moveXUnits.length > 0 &&
168
+ moveYUnits.length > 0 &&
169
+ opts.dx > 0 &&
170
+ opts.dy > 0) {
171
+ const mouseX100 = (e.clientX - containerRect.left + node.scrollLeft) / opts.dx;
172
+ const xIdx = findContainingUnit(mouseX100, moveXUnits);
173
+ newLeft =
174
+ origLeft +
175
+ (moveXUnits[xIdx].position - moveXUnits[grabXIdx].position) * opts.dx;
176
+ const mouseY100 = (e.clientY - containerRect.top + node.scrollTop) / opts.dy;
177
+ const yIdx = findContainingUnit(mouseY100, moveYUnits);
178
+ newTop =
179
+ origTop +
180
+ (moveYUnits[yIdx].position - moveYUnits[grabYIdx].position) * opts.dy;
181
+ }
182
+ else {
183
+ newLeft = rawX;
184
+ newTop = rawY;
185
+ }
186
+ if (opts.clipDrag) {
187
+ const maxX = Math.max(node.scrollWidth, node.clientWidth) - moveEl.offsetWidth;
188
+ const maxY = Math.max(node.scrollHeight, node.clientHeight) - moveEl.offsetHeight;
189
+ newLeft = clamp(newLeft, 0, maxX);
190
+ newTop = clamp(newTop, 0, maxY);
191
+ }
192
+ moveEl.style.left = newLeft + "px";
193
+ moveEl.style.top = newTop + "px";
194
+ }
195
+ function handleMoveMouseUp(e) {
196
+ document.removeEventListener("mousemove", handleMoveMouseMove);
197
+ document.removeEventListener("mouseup", handleMoveMouseUp);
198
+ if (!moveActive || !moveEl) {
199
+ resetMove();
200
+ return;
201
+ }
202
+ const eventId = getID(moveEl);
203
+ const original = opts.getEvent(eventId);
204
+ if (!original) {
205
+ resetMove();
206
+ return;
207
+ }
208
+ if (opts.mode === "grid" &&
209
+ moveXUnits.length > 0 &&
210
+ moveYUnits.length > 0 &&
211
+ opts.dx > 0 &&
212
+ opts.dy > 0) {
213
+ const containerRect = node.getBoundingClientRect();
214
+ const mouseX100 = (e.clientX - containerRect.left + node.scrollLeft) / opts.dx;
215
+ const mouseY100 = (e.clientY - containerRect.top + node.scrollTop) / opts.dy;
216
+ const dropXIdx = findContainingUnit(mouseX100, moveXUnits);
217
+ const dropYIdx = findContainingUnit(mouseY100, moveYUnits);
218
+ const xDelta = dropXIdx - grabXIdx;
219
+ const yDelta = dropYIdx - grabYIdx;
220
+ if (xDelta !== 0 || yDelta !== 0) {
221
+ const xStepMs = moveXUnits.length >= 2
222
+ ? moveXUnits[1].ui.date.getTime() -
223
+ moveXUnits[0].ui.date.getTime()
224
+ : 86400000;
225
+ const yStepMs = moveYUnits.length >= 2
226
+ ? moveYUnits[1].ui.date.getTime() -
227
+ moveYUnits[0].ui.date.getTime()
228
+ : 7 * 86400000;
229
+ const deltaMs = xDelta * xStepMs + yDelta * yStepMs;
230
+ const newStart = new Date(original.start.getTime() + deltaMs);
231
+ const duration = original.duration != null
232
+ ? original.duration
233
+ : original.end
234
+ ? original.end.getTime() - original.start.getTime()
235
+ : 0;
236
+ const newEnd = new Date(newStart.getTime() + duration);
237
+ const payload = {
238
+ id: original.id,
239
+ event: { start: newStart, end: newEnd },
240
+ };
241
+ opts.exec("update-event", payload);
242
+ }
243
+ resetMove();
244
+ return;
245
+ }
246
+ const finalLeft = parseFloat(moveEl.style.left) || 0;
247
+ const finalTop = parseFloat(moveEl.style.top) || 0;
248
+ let x100;
249
+ let y100;
250
+ if (opts.mode === "bars") {
251
+ x100 = opts.dx > 0 ? finalLeft / opts.dx : 0;
252
+ y100 = opts.dy > 0 ? (finalTop + moveEl.offsetHeight / 2) / opts.dy : 0;
253
+ }
254
+ else if (opts.mode === "boxes") {
255
+ x100 = opts.dx > 0 ? (finalLeft + moveEl.offsetWidth / 2) / opts.dx : 0;
256
+ y100 = opts.dy > 0 ? finalTop / opts.dy : 0;
257
+ }
258
+ else {
259
+ x100 = opts.dx > 0 ? finalLeft / opts.dx : 0;
260
+ y100 = opts.dy > 0 ? finalTop / opts.dy : 0;
261
+ }
262
+ const duration = original.duration != null
263
+ ? original.duration
264
+ : original.end
265
+ ? original.end.getTime() - original.start.getTime()
266
+ : 0;
267
+ if (duration > 0) {
268
+ const partial = opts.model.toPositionStart(opts.sectionName, x100, y100, { start: original.start }, true);
269
+ if (partial.start instanceof Date) {
270
+ partial.end = new Date(partial.start.getTime() + duration);
271
+ const payload = {
272
+ id: original.id,
273
+ event: partial,
274
+ };
275
+ opts.exec("update-event", payload);
276
+ }
277
+ }
278
+ resetMove();
279
+ }
280
+ function cancelMove() {
281
+ document.removeEventListener("mousemove", handleMoveMouseMove);
282
+ document.removeEventListener("mouseup", handleMoveMouseUp);
283
+ resetMove();
284
+ }
285
+ function resetMove() {
286
+ if (moveEl) {
287
+ moveEl.style.cssText = moveOrigStyle;
288
+ moveEl.classList.remove("wx-dragging");
289
+ }
290
+ document.body.style.userSelect = "";
291
+ moveEl = null;
292
+ movePending = false;
293
+ moveActive = false;
294
+ }
295
+ // ---- create ----
296
+ function startCreate(e) {
297
+ stub = node.querySelector("[data-drag-stub]");
298
+ if (!stub)
299
+ return;
300
+ e.preventDefault();
301
+ createPending = true;
302
+ createActive = false;
303
+ createStartX = e.clientX;
304
+ createStartY = e.clientY;
305
+ createXUnits = opts.xHeaders?.[opts.xHeaders.length - 1] ?? [];
306
+ createYUnits = opts.yHeaders?.[opts.yHeaders.length - 1] ?? [];
307
+ const containerRect = node.getBoundingClientRect();
308
+ if (opts.mode === "grid") {
309
+ const mouseX100 = (e.clientX - containerRect.left + node.scrollLeft) / opts.dx;
310
+ const mouseY100 = (e.clientY - containerRect.top + node.scrollTop) / opts.dy;
311
+ anchorXIdx = findContainingUnit(mouseX100, createXUnits);
312
+ anchorYIdx = findContainingUnit(mouseY100, createYUnits);
313
+ }
314
+ else if (opts.mode === "boxes") {
315
+ if (createXUnits.length > 0) {
316
+ const mouseX100 = (e.clientX - containerRect.left + node.scrollLeft) / opts.dx;
317
+ anchorXIdx2 = findContainingUnit(mouseX100, createXUnits);
318
+ }
319
+ anchorY = e.clientY - containerRect.top + node.scrollTop;
320
+ }
321
+ else if (opts.mode === "bars") {
322
+ if (createYUnits.length > 0) {
323
+ const mouseY100 = (e.clientY - containerRect.top + node.scrollTop) / opts.dy;
324
+ anchorYIdx2 = findContainingUnit(mouseY100, createYUnits);
325
+ }
326
+ anchorX = e.clientX - containerRect.left + node.scrollLeft;
327
+ }
328
+ document.addEventListener("mousemove", handleCreateMouseMove);
329
+ document.addEventListener("mouseup", handleCreateMouseUp);
330
+ }
331
+ function handleCreateMouseMove(e) {
332
+ if (!stub)
333
+ return;
334
+ if (createPending) {
335
+ const dx = Math.abs(e.clientX - createStartX);
336
+ const dy = Math.abs(e.clientY - createStartY);
337
+ if (dx < CREATE_THRESHOLD && dy < CREATE_THRESHOLD)
338
+ return;
339
+ createPending = false;
340
+ createActive = true;
341
+ stub.style.display = "block";
342
+ document.body.style.userSelect = "none";
343
+ }
344
+ if (!createActive)
345
+ return;
346
+ const containerRect = node.getBoundingClientRect();
347
+ if (opts.mode === "grid" &&
348
+ createXUnits.length > 0 &&
349
+ createYUnits.length > 0) {
350
+ const mouseX100 = (e.clientX - containerRect.left + node.scrollLeft) / opts.dx;
351
+ const cursorXIdx = findContainingUnit(mouseX100, createXUnits);
352
+ const minIdx = Math.min(anchorXIdx, cursorXIdx);
353
+ const maxIdx = Math.max(anchorXIdx, cursorXIdx);
354
+ const left = createXUnits[minIdx].position * opts.dx;
355
+ const right = maxIdx < createXUnits.length - 1
356
+ ? createXUnits[maxIdx + 1].position * opts.dx
357
+ : (createXUnits[maxIdx].position + createXUnits[maxIdx].size) *
358
+ opts.dx;
359
+ const top = createYUnits[anchorYIdx].position * opts.dy;
360
+ const height = createYUnits[anchorYIdx].size * opts.dy;
361
+ stub.style.left = left + "px";
362
+ stub.style.top = top + "px";
363
+ stub.style.width = right - left + "px";
364
+ stub.style.height = height + "px";
365
+ }
366
+ else if (opts.mode === "boxes") {
367
+ const cursorY = e.clientY - containerRect.top + node.scrollTop;
368
+ const minY = Math.min(anchorY, cursorY);
369
+ const maxY = Math.max(anchorY, cursorY);
370
+ let left, width;
371
+ if (createXUnits.length > 0) {
372
+ left = createXUnits[anchorXIdx2].position * opts.dx;
373
+ width = createXUnits[anchorXIdx2].size * opts.dx;
374
+ }
375
+ else {
376
+ left = 0;
377
+ width = node.scrollWidth || node.clientWidth;
378
+ }
379
+ stub.style.left = left + "px";
380
+ stub.style.top = minY + "px";
381
+ stub.style.width = width + "px";
382
+ stub.style.height = maxY - minY + "px";
383
+ }
384
+ else if (opts.mode === "bars") {
385
+ const cursorX = e.clientX - containerRect.left + node.scrollLeft;
386
+ const minX = Math.min(anchorX, cursorX);
387
+ const maxX = Math.max(anchorX, cursorX);
388
+ let top, height;
389
+ if (createYUnits.length > 0) {
390
+ top = createYUnits[anchorYIdx2].position * opts.dy;
391
+ height = createYUnits[anchorYIdx2].size * opts.dy;
392
+ }
393
+ else {
394
+ top = 0;
395
+ height = node.scrollHeight || node.clientHeight;
396
+ }
397
+ stub.style.left = minX + "px";
398
+ stub.style.top = top + "px";
399
+ stub.style.width = maxX - minX + "px";
400
+ stub.style.height = height + "px";
401
+ }
402
+ }
403
+ function handleCreateMouseUp(e) {
404
+ document.removeEventListener("mousemove", handleCreateMouseMove);
405
+ document.removeEventListener("mouseup", handleCreateMouseUp);
406
+ if (!createActive || !stub) {
407
+ resetCreate();
408
+ return;
409
+ }
410
+ const containerRect = node.getBoundingClientRect();
411
+ if (opts.mode === "grid" &&
412
+ createXUnits.length > 0 &&
413
+ createYUnits.length > 0) {
414
+ const mouseX100 = (e.clientX - containerRect.left + node.scrollLeft) / opts.dx;
415
+ const cursorXIdx = findContainingUnit(mouseX100, createXUnits);
416
+ const startXIdx = Math.min(anchorXIdx, cursorXIdx);
417
+ const endXIdx = Math.max(anchorXIdx, cursorXIdx);
418
+ const xStepMs = createXUnits.length >= 2
419
+ ? createXUnits[1].ui.date.getTime() -
420
+ createXUnits[0].ui.date.getTime()
421
+ : 86400000;
422
+ const rowStart = createYUnits[anchorYIdx].ui.date.getTime();
423
+ const start = new Date(rowStart + startXIdx * xStepMs);
424
+ const end = new Date(rowStart + (endXIdx + 1) * xStepMs);
425
+ opts.exec("add-event", { event: { start, end }, edit: true });
426
+ }
427
+ else if (opts.mode === "boxes") {
428
+ const cursorY = e.clientY - containerRect.top + node.scrollTop;
429
+ const minY = Math.min(anchorY, cursorY);
430
+ const maxY = Math.max(anchorY, cursorY);
431
+ const x100 = createXUnits.length > 0
432
+ ? createXUnits[anchorXIdx2].position +
433
+ createXUnits[anchorXIdx2].size / 2
434
+ : 50;
435
+ const startY100 = opts.dy > 0 ? minY / opts.dy : 0;
436
+ const endY100 = opts.dy > 0 ? maxY / opts.dy : 0;
437
+ const startPartial = opts.model.toPositionStart(opts.sectionName, x100, startY100, {}, true);
438
+ const endPartial = opts.model.toPositionEnd(opts.sectionName, x100, endY100, {}, true);
439
+ if (startPartial.start instanceof Date &&
440
+ endPartial.end instanceof Date) {
441
+ opts.exec("add-event", {
442
+ event: { ...startPartial, ...endPartial },
443
+ edit: true,
444
+ });
445
+ }
446
+ }
447
+ else if (opts.mode === "bars") {
448
+ const cursorX = e.clientX - containerRect.left + node.scrollLeft;
449
+ const minX = Math.min(anchorX, cursorX);
450
+ const maxX = Math.max(anchorX, cursorX);
451
+ const y100 = createYUnits.length > 0
452
+ ? createYUnits[anchorYIdx2].position +
453
+ createYUnits[anchorYIdx2].size / 2
454
+ : 50;
455
+ const startX100 = opts.dx > 0 ? minX / opts.dx : 0;
456
+ const endX100 = opts.dx > 0 ? maxX / opts.dx : 0;
457
+ const startPartial = opts.model.toPositionStart(opts.sectionName, startX100, y100, {}, true);
458
+ const endPartial = opts.model.toPositionEnd(opts.sectionName, endX100, y100, {}, true);
459
+ if (startPartial.start instanceof Date &&
460
+ endPartial.end instanceof Date) {
461
+ opts.exec("add-event", {
462
+ event: { ...startPartial, ...endPartial },
463
+ edit: true,
464
+ });
465
+ }
466
+ }
467
+ resetCreate();
468
+ }
469
+ function resetCreate() {
470
+ if (stub)
471
+ stub.style.display = "none";
472
+ document.body.style.userSelect = "";
473
+ stub = null;
474
+ createActive = false;
475
+ createPending = false;
476
+ }
477
+ // ---- lifecycle ----
478
+ node.addEventListener("mousedown", handleMouseDown);
479
+ return {
480
+ update(newOpts) {
481
+ opts = newOpts;
482
+ },
483
+ destroy() {
484
+ node.removeEventListener("mousedown", handleMouseDown);
485
+ if (moveActive || movePending)
486
+ cancelMove();
487
+ if (createActive || createPending) {
488
+ document.removeEventListener("mousemove", handleCreateMouseMove);
489
+ document.removeEventListener("mouseup", handleCreateMouseUp);
490
+ resetCreate();
491
+ }
492
+ },
493
+ };
494
+ }
@@ -0,0 +1,10 @@
1
+ import type { EventID, ViewModel, CalendarEvent, StoreActions } from "@svar-ui/calendar-store";
2
+ export interface ResizeOptions {
3
+ dx: number;
4
+ dy: number;
5
+ sectionName: string;
6
+ model: ViewModel;
7
+ exec: (action: keyof StoreActions, data: any) => unknown;
8
+ getEvent: (id: EventID) => CalendarEvent | undefined;
9
+ }
10
+ export declare function startResize(node: HTMLElement, dragEl: HTMLElement, e: MouseEvent, eventId: EventID, opts: ResizeOptions): void;
@@ -0,0 +1,58 @@
1
+ const DRAG_THRESHOLD = 3;
2
+ export function startResize(node, dragEl, e, eventId, opts) {
3
+ const origStyle = dragEl.style.cssText;
4
+ const origTop = parseFloat(dragEl.style.top) || 0;
5
+ const startClientY = e.clientY;
6
+ let active = false;
7
+ e.preventDefault();
8
+ e.stopPropagation();
9
+ dragEl.style.zIndex = "100";
10
+ dragEl.style.transition = "none";
11
+ document.body.style.userSelect = "none";
12
+ document.body.style.cursor = "s-resize";
13
+ function handleMouseMove(ev) {
14
+ if (!active) {
15
+ if (Math.abs(ev.clientY - startClientY) < DRAG_THRESHOLD)
16
+ return;
17
+ active = true;
18
+ dragEl.classList.add("wx-resizing");
19
+ }
20
+ const containerRect = node.getBoundingClientRect();
21
+ const cursorY = ev.clientY - containerRect.top + node.scrollTop;
22
+ const newHeight = Math.max(10, cursorY - origTop);
23
+ dragEl.style.height = newHeight + "px";
24
+ }
25
+ function handleMouseUp() {
26
+ document.removeEventListener("mousemove", handleMouseMove);
27
+ document.removeEventListener("mouseup", handleMouseUp);
28
+ if (!active) {
29
+ reset();
30
+ return;
31
+ }
32
+ const finalBottom = origTop + (parseFloat(dragEl.style.height) || dragEl.offsetHeight);
33
+ const original = opts.getEvent(eventId);
34
+ if (original) {
35
+ // x100: center of the element's column
36
+ const finalLeft = parseFloat(dragEl.style.left) || 0;
37
+ const x100 = opts.dx > 0 ? (finalLeft + dragEl.offsetWidth / 2) / opts.dx : 0;
38
+ const endY100 = opts.dy > 0 ? finalBottom / opts.dy : 0;
39
+ const endPartial = opts.model.toPositionEnd(opts.sectionName, x100, endY100, { end: original.end }, true);
40
+ if (endPartial.end instanceof Date) {
41
+ const payload = {
42
+ id: original.id,
43
+ event: { end: endPartial.end },
44
+ };
45
+ opts.exec("update-event", payload);
46
+ }
47
+ }
48
+ reset();
49
+ }
50
+ function reset() {
51
+ dragEl.style.cssText = origStyle;
52
+ dragEl.classList.remove("wx-resizing");
53
+ document.body.style.userSelect = "";
54
+ document.body.style.cursor = "";
55
+ }
56
+ document.addEventListener("mousemove", handleMouseMove);
57
+ document.addEventListener("mouseup", handleMouseUp);
58
+ }
@@ -0,0 +1,5 @@
1
+ type ResizeCallback = (rect: DOMRect) => void;
2
+ export declare function resize(node: HTMLElement, callback: ResizeCallback): {
3
+ destroy: () => void;
4
+ };
5
+ export {};
@@ -0,0 +1,11 @@
1
+ export function resize(node, callback) {
2
+ const observer = new ResizeObserver(entries => {
3
+ for (const entry of entries) {
4
+ callback(entry.contentRect);
5
+ }
6
+ });
7
+ observer.observe(node);
8
+ return {
9
+ destroy: () => observer.disconnect(),
10
+ };
11
+ }
package/dist/dom.d.ts ADDED
@@ -0,0 +1 @@
1
+ export declare function getScrollbarSize(): number;
package/dist/dom.js ADDED
@@ -0,0 +1,12 @@
1
+ let scrollbarSize = null;
2
+ export function getScrollbarSize() {
3
+ if (scrollbarSize !== null)
4
+ return scrollbarSize;
5
+ const outer = document.createElement("div");
6
+ outer.style.cssText =
7
+ "position:absolute;top:-9999px;width:100px;height:100px;overflow:scroll";
8
+ document.body.appendChild(outer);
9
+ scrollbarSize = outer.offsetWidth - outer.clientWidth;
10
+ document.body.removeChild(outer);
11
+ return scrollbarSize;
12
+ }
package/dist/env.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ /// <reference types="svelte" />
2
+ declare module "@svar-ui/calendar-locales";
3
+ declare module "@svar-ui/core-locales";
4
+
5
+ declare module "*.svelte" {
6
+ import type { Component } from "svelte";
7
+ const component: Component<any>;
8
+ export default component;
9
+ }
@@ -0,0 +1,14 @@
1
+ import Calendar from "./components/Calendar.svelte";
2
+ import CalendarPanel from "./components/CalendarPanel.svelte";
3
+ import ContextMenu from "./components/ContextMenu.svelte";
4
+ import Editor from "./components/Editor.svelte";
5
+ import Willow from "./themes/Willow.svelte";
6
+ import WillowDark from "./themes/WillowDark.svelte";
7
+ export { getToolbarItems, getMenuOptions, registerCalendarView, WeekViewModel, DayViewModel, MonthViewModel, } from "@svar-ui/calendar-store";
8
+ export type { ToolbarItem, CalendarEvent, CellContext, EventContext, EventContentMode, CellCss, EventCss, } from "@svar-ui/calendar-store";
9
+ export type { CalendarContextApi, CalendarInstanceApi, ViewOption, } from "./components/types.js";
10
+ export { getEditorItems } from "./components/editorItems.js";
11
+ export { registerEditorItem } from "@svar-ui/svelte-editor";
12
+ export { parseICal, serializeICal } from "@svar-ui/calendar-ical";
13
+ export { RestDataProvider } from "@svar-ui/calendar-provider";
14
+ export { Calendar, CalendarPanel, ContextMenu, Editor, Willow, WillowDark };
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ import Calendar from "./components/Calendar.svelte";
2
+ import CalendarPanel from "./components/CalendarPanel.svelte";
3
+ import ContextMenu from "./components/ContextMenu.svelte";
4
+ import Editor from "./components/Editor.svelte";
5
+ import Willow from "./themes/Willow.svelte";
6
+ import WillowDark from "./themes/WillowDark.svelte";
7
+ export { getToolbarItems, getMenuOptions, registerCalendarView, WeekViewModel, DayViewModel, MonthViewModel, } from "@svar-ui/calendar-store";
8
+ export { getEditorItems } from "./components/editorItems.js";
9
+ export { registerEditorItem } from "@svar-ui/svelte-editor";
10
+ export { parseICal, serializeICal } from "@svar-ui/calendar-ical";
11
+ export { RestDataProvider } from "@svar-ui/calendar-provider";
12
+ export { Calendar, CalendarPanel, ContextMenu, Editor, Willow, WillowDark };
package/dist/init.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};
package/dist/init.js ADDED
@@ -0,0 +1,5 @@
1
+ import { mount } from "svelte";
2
+ import Demo from "./Demo.svelte";
3
+ mount(Demo, {
4
+ target: document.querySelector("#wx_demo_area") || document.body,
5
+ });
@@ -0,0 +1,16 @@
1
+ <script lang="ts">import { Willow } from "@svar-ui/svelte-core";
2
+ let { fonts = true, children } = $props();
3
+ </script>
4
+
5
+ {#if children}
6
+ <Willow {fonts}>{@render children()}</Willow>
7
+ {:else}
8
+ <Willow {fonts} />
9
+ {/if}
10
+
11
+ <style>
12
+ :global(.wx-willow-theme) {
13
+ --wx-calendar-grid-color: #e6e6e6;
14
+ --wx-calendar-weekend-background: #fbf9ff;
15
+ }
16
+ </style>
@@ -0,0 +1,7 @@
1
+ import { Willow } from "@svar-ui/svelte-core";
2
+ declare const Willow: import("svelte").Component<{
3
+ fonts?: boolean;
4
+ children: any;
5
+ }, {}, "">;
6
+ type Willow = ReturnType<typeof Willow>;
7
+ export default Willow;