@dodlhuat/basix 1.4.1 → 1.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -1
- package/css/calendar.scss +4 -3
- package/css/code-viewer.scss +1 -1
- package/css/datepicker.scss +83 -70
- package/css/editor.scss +2 -1
- package/css/flyout-menu.scss +2 -1
- package/css/form.scss +11 -32
- package/css/mixins.scss +25 -0
- package/css/range-slider.scss +63 -6
- package/css/stepper.scss +2 -1
- package/css/style.css +124 -71
- package/css/style.css.map +1 -1
- package/css/style.min.css +1 -1
- package/css/style.min.css.map +1 -1
- package/css/timepicker.scss +1 -1
- package/css/virtual-dropdown.scss +6 -16
- package/js/bottom-sheet.d.ts +3 -5
- package/js/bottom-sheet.js +39 -58
- package/js/calendar.d.ts +1 -2
- package/js/calendar.js +77 -84
- package/js/carousel.d.ts +1 -1
- package/js/carousel.js +22 -14
- package/js/chart.d.ts +1 -1
- package/js/chart.js +104 -65
- package/js/code-viewer.d.ts +1 -1
- package/js/code-viewer.js +7 -18
- package/js/color-picker.d.ts +2 -2
- package/js/color-picker.js +20 -22
- package/js/context-menu.d.ts +1 -1
- package/js/context-menu.js +10 -12
- package/js/datepicker.d.ts +14 -3
- package/js/datepicker.js +180 -99
- package/js/dropdown.d.ts +1 -1
- package/js/dropdown.js +4 -5
- package/js/editor.d.ts +1 -1
- package/js/editor.js +30 -34
- package/js/file-uploader.d.ts +2 -9
- package/js/file-uploader.js +57 -86
- package/js/flyout-menu.d.ts +3 -3
- package/js/flyout-menu.js +20 -22
- package/js/gallery.d.ts +1 -2
- package/js/gallery.js +14 -20
- package/js/group-picker.d.ts +1 -1
- package/js/group-picker.js +22 -29
- package/js/lightbox.d.ts +2 -2
- package/js/lightbox.js +28 -27
- package/js/listeners.d.ts +7 -0
- package/js/listeners.js +14 -0
- package/js/modal.d.ts +2 -1
- package/js/modal.js +13 -20
- package/js/popover.d.ts +2 -2
- package/js/popover.js +42 -37
- package/js/position.js +3 -5
- package/js/push-menu.d.ts +2 -0
- package/js/push-menu.js +21 -15
- package/js/range-slider.d.ts +15 -1
- package/js/range-slider.js +67 -7
- package/js/scroll.js +4 -7
- package/js/scrollbar.d.ts +3 -3
- package/js/scrollbar.js +39 -42
- package/js/select.d.ts +1 -1
- package/js/select.js +19 -23
- package/js/sidebar-nav.d.ts +1 -1
- package/js/sidebar-nav.js +13 -9
- package/js/stepper.d.ts +1 -1
- package/js/stepper.js +9 -11
- package/js/table.d.ts +1 -1
- package/js/table.js +24 -23
- package/js/tabs.d.ts +1 -1
- package/js/tabs.js +10 -17
- package/js/theme.d.ts +1 -0
- package/js/theme.js +6 -15
- package/js/timepicker.d.ts +8 -6
- package/js/timepicker.js +36 -36
- package/js/toast.d.ts +2 -1
- package/js/toast.js +8 -4
- package/js/tooltip.d.ts +1 -4
- package/js/tooltip.js +14 -23
- package/js/tree.d.ts +0 -1
- package/js/tree.js +6 -11
- package/js/utils.js +7 -8
- package/js/virtual-dropdown.d.ts +1 -1
- package/js/virtual-dropdown.js +26 -28
- package/package.json +1 -1
- package/css/calendar.css +0 -928
- package/css/guitar-chords.css +0 -251
- package/js/form-builder.js +0 -107
- package/js/guitar-chords.js +0 -268
- package/js/lazy-loader.js +0 -121
- package/js/request.js +0 -51
package/js/calendar.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ListenerGroup } from './listeners.js';
|
|
1
2
|
const CalendarLogic = {
|
|
2
3
|
getMonthGrid(year, month, firstDayOfWeek) {
|
|
3
4
|
const firstOfMonth = new Date(year, month, 1);
|
|
@@ -30,9 +31,7 @@ const CalendarLogic = {
|
|
|
30
31
|
});
|
|
31
32
|
},
|
|
32
33
|
isSameDay(a, b) {
|
|
33
|
-
return a.getFullYear() === b.getFullYear()
|
|
34
|
-
&& a.getMonth() === b.getMonth()
|
|
35
|
-
&& a.getDate() === b.getDate();
|
|
34
|
+
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
36
35
|
},
|
|
37
36
|
isToday(date) {
|
|
38
37
|
return CalendarLogic.isSameDay(date, new Date());
|
|
@@ -53,13 +52,13 @@ const CalendarLogic = {
|
|
|
53
52
|
dayStart.setHours(0, 0, 0, 0);
|
|
54
53
|
const dayEnd = new Date(day);
|
|
55
54
|
dayEnd.setHours(23, 59, 59, 999);
|
|
56
|
-
return events.filter(e => e.start <= dayEnd && e.end >= dayStart);
|
|
55
|
+
return events.filter((e) => e.start <= dayEnd && e.end >= dayStart);
|
|
57
56
|
},
|
|
58
57
|
getAllDayEvents(events, day) {
|
|
59
|
-
return CalendarLogic.getEventsForDay(events, day).filter(e => e.allDay);
|
|
58
|
+
return CalendarLogic.getEventsForDay(events, day).filter((e) => e.allDay);
|
|
60
59
|
},
|
|
61
60
|
getTimedEvents(events, day) {
|
|
62
|
-
return CalendarLogic.getEventsForDay(events, day).filter(e => !e.allDay);
|
|
61
|
+
return CalendarLogic.getEventsForDay(events, day).filter((e) => !e.allDay);
|
|
63
62
|
},
|
|
64
63
|
getEventPosition(event, day) {
|
|
65
64
|
const dayStart = new Date(day);
|
|
@@ -82,7 +81,7 @@ const CalendarLogic = {
|
|
|
82
81
|
return [];
|
|
83
82
|
const weekStart = CalendarLogic.startOfDay(weekDays[0]);
|
|
84
83
|
const weekEnd = CalendarLogic.startOfDay(weekDays[6]);
|
|
85
|
-
const relevant = events.filter(e => {
|
|
84
|
+
const relevant = events.filter((e) => {
|
|
86
85
|
const s = CalendarLogic.startOfDay(e.start);
|
|
87
86
|
const en = CalendarLogic.startOfDay(e.end);
|
|
88
87
|
return s <= weekEnd && en >= weekStart;
|
|
@@ -91,7 +90,7 @@ const CalendarLogic = {
|
|
|
91
90
|
const diff = a.start.getTime() - b.start.getTime();
|
|
92
91
|
if (diff !== 0)
|
|
93
92
|
return diff;
|
|
94
|
-
return
|
|
93
|
+
return b.end.getTime() - b.start.getTime() - (a.end.getTime() - a.start.getTime());
|
|
95
94
|
});
|
|
96
95
|
const laneEnds = [];
|
|
97
96
|
const layouts = [];
|
|
@@ -136,7 +135,7 @@ const CalendarLogic = {
|
|
|
136
135
|
const diff = a.start.getTime() - b.start.getTime();
|
|
137
136
|
if (diff !== 0)
|
|
138
137
|
return diff;
|
|
139
|
-
return
|
|
138
|
+
return b.end.getTime() - b.start.getTime() - (a.end.getTime() - a.start.getTime());
|
|
140
139
|
});
|
|
141
140
|
const colEnds = [];
|
|
142
141
|
const assigns = [];
|
|
@@ -151,23 +150,18 @@ const CalendarLogic = {
|
|
|
151
150
|
assigns.push({ event, col });
|
|
152
151
|
}
|
|
153
152
|
return assigns.map(({ event, col }) => {
|
|
154
|
-
const cols = assigns
|
|
155
|
-
.filter(a => a.event.start < event.end && a.event.end > event.start)
|
|
156
|
-
.reduce((max, a) => Math.max(max, a.col), 0) + 1;
|
|
153
|
+
const cols = assigns.filter((a) => a.event.start < event.end && a.event.end > event.start).reduce((max, a) => Math.max(max, a.col), 0) + 1;
|
|
157
154
|
const pos = CalendarLogic.getEventPosition(event, day);
|
|
158
155
|
return { event, top: pos.top, height: pos.height, col, cols };
|
|
159
156
|
});
|
|
160
157
|
},
|
|
161
158
|
nowLinePct() {
|
|
162
159
|
const now = new Date();
|
|
163
|
-
return (now.getHours() * 60 + now.getMinutes()) / 1440 * 100;
|
|
160
|
+
return ((now.getHours() * 60 + now.getMinutes()) / 1440) * 100;
|
|
164
161
|
},
|
|
165
162
|
};
|
|
166
163
|
const DEFAULT_LOCALE = {
|
|
167
|
-
monthNames: [
|
|
168
|
-
'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni',
|
|
169
|
-
'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember',
|
|
170
|
-
],
|
|
164
|
+
monthNames: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
|
|
171
165
|
dayNamesShort: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
|
|
172
166
|
dayNamesFull: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
|
|
173
167
|
firstDayOfWeek: 1,
|
|
@@ -185,13 +179,8 @@ class CalendarRenderer {
|
|
|
185
179
|
}
|
|
186
180
|
renderWeekdayHeaders() {
|
|
187
181
|
const { dayNamesShort, firstDayOfWeek } = this.locale;
|
|
188
|
-
const ordered = [
|
|
189
|
-
|
|
190
|
-
...dayNamesShort.slice(0, firstDayOfWeek),
|
|
191
|
-
];
|
|
192
|
-
return ordered
|
|
193
|
-
.map(name => `<div class="cal__weekday" aria-label="${name}">${name}</div>`)
|
|
194
|
-
.join('');
|
|
182
|
+
const ordered = [...dayNamesShort.slice(firstDayOfWeek), ...dayNamesShort.slice(0, firstDayOfWeek)];
|
|
183
|
+
return ordered.map((name) => `<div class="cal__weekday" aria-label="${name}">${name}</div>`).join('');
|
|
195
184
|
}
|
|
196
185
|
renderEvent(event, compact = false) {
|
|
197
186
|
const cls = event.className ?? '';
|
|
@@ -211,7 +200,9 @@ class CalendarRenderer {
|
|
|
211
200
|
event.className ?? '',
|
|
212
201
|
continuesBefore ? 'cal__span-bar--cont-before' : '',
|
|
213
202
|
continuesAfter ? 'cal__span-bar--cont-after' : '',
|
|
214
|
-
]
|
|
203
|
+
]
|
|
204
|
+
.filter(Boolean)
|
|
205
|
+
.join(' ');
|
|
215
206
|
return `<div class="${cls}"
|
|
216
207
|
style="--span-col:${colStart};--span-len:${colSpan};--span-lane:${lane}"
|
|
217
208
|
data-event-id="${event.id}"
|
|
@@ -225,30 +216,28 @@ class CalendarRenderer {
|
|
|
225
216
|
return `<div class="cal__day cal__day--empty" aria-hidden="true"></div>`;
|
|
226
217
|
}
|
|
227
218
|
const allForDay = CalendarLogic.getEventsForDay(events, date);
|
|
228
|
-
const pillEvents = allForDay.filter(e => !CalendarLogic.isMultiDay(e));
|
|
219
|
+
const pillEvents = allForDay.filter((e) => !CalendarLogic.isMultiDay(e));
|
|
229
220
|
const isToday = CalendarLogic.isToday(date);
|
|
230
|
-
const classes = [
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
221
|
+
const classes = ['cal__day', isToday ? 'is-today' : '', isOutside ? 'cal__day--outside' : '', allForDay.length > 0 ? 'has-events' : '']
|
|
222
|
+
.filter(Boolean)
|
|
223
|
+
.join(' ');
|
|
224
|
+
const eventsHtml = pillEvents
|
|
225
|
+
.slice(0, 3)
|
|
226
|
+
.map((e) => this.renderEvent(e, true))
|
|
227
|
+
.join('');
|
|
237
228
|
const moreCount = pillEvents.length - 3;
|
|
238
229
|
const moreHtml = moreCount > 0 ? `<div class="cal__event-more">+${moreCount}</div>` : '';
|
|
239
|
-
return `<div class="${classes}" aria-label="${date.toLocaleDateString()}">
|
|
230
|
+
return `<div class="${classes}" data-date="${date.toISOString()}" aria-label="${date.toLocaleDateString()}">
|
|
240
231
|
<span class="cal__day-num">${date.getDate()}</span>
|
|
241
232
|
<div class="cal__day-events">${eventsHtml}${moreHtml}</div>
|
|
242
233
|
</div>`;
|
|
243
234
|
}
|
|
244
235
|
renderWeekRow(weekDays, currentMonth, currentYear, events, showOutsideDays) {
|
|
245
|
-
const multiDay = events.filter(e => CalendarLogic.isMultiDay(e));
|
|
236
|
+
const multiDay = events.filter((e) => CalendarLogic.isMultiDay(e));
|
|
246
237
|
const spans = CalendarLogic.computeSpanLayout(weekDays, multiDay);
|
|
247
|
-
const maxLanes = spans.length > 0 ? Math.max(...spans.map(s => s.lane)) + 1 : 0;
|
|
248
|
-
const dayCells = weekDays
|
|
249
|
-
|
|
250
|
-
.join('');
|
|
251
|
-
const spanBars = spans.map(s => this.renderSpanBar(s)).join('');
|
|
238
|
+
const maxLanes = spans.length > 0 ? Math.max(...spans.map((s) => s.lane)) + 1 : 0;
|
|
239
|
+
const dayCells = weekDays.map((d) => this.renderMonthDay(d, currentMonth, currentYear, events, showOutsideDays)).join('');
|
|
240
|
+
const spanBars = spans.map((s) => this.renderSpanBar(s)).join('');
|
|
252
241
|
return `<div class="cal__week-row" style="--span-lanes:${maxLanes}">
|
|
253
242
|
${dayCells}${spanBars}
|
|
254
243
|
</div>`;
|
|
@@ -266,31 +255,34 @@ class CalendarRenderer {
|
|
|
266
255
|
}
|
|
267
256
|
renderWeekView(date, events, firstDayOfWeek, showNowLine = false) {
|
|
268
257
|
const days = CalendarLogic.getWeekDays(date, firstDayOfWeek);
|
|
269
|
-
const headCols = days
|
|
258
|
+
const headCols = days
|
|
259
|
+
.map((d) => {
|
|
270
260
|
const isToday = CalendarLogic.isToday(d);
|
|
271
|
-
const cls = ['cal__week-head-day', isToday ? 'is-today' : '']
|
|
272
|
-
.filter(Boolean).join(' ');
|
|
261
|
+
const cls = ['cal__week-head-day', isToday ? 'is-today' : ''].filter(Boolean).join(' ');
|
|
273
262
|
const dow = this.locale.dayNamesShort[(d.getDay() + 7) % 7];
|
|
274
263
|
return `<div class="${cls}">${dow}<span>${d.getDate()}</span></div>`;
|
|
275
|
-
})
|
|
276
|
-
|
|
264
|
+
})
|
|
265
|
+
.join('');
|
|
266
|
+
const allDayEvents = events.filter((e) => e.allDay);
|
|
277
267
|
const allDayLayouts = CalendarLogic.computeSpanLayout(days, allDayEvents);
|
|
278
|
-
const allDayLanes = allDayLayouts.length > 0 ? Math.max(...allDayLayouts.map(l => l.lane)) + 1 : 0;
|
|
268
|
+
const allDayLanes = allDayLayouts.length > 0 ? Math.max(...allDayLayouts.map((l) => l.lane)) + 1 : 0;
|
|
279
269
|
const allDayCols = days.map(() => `<div class="cal__allday-col"></div>`).join('');
|
|
280
|
-
const allDayBars = allDayLayouts.map(l => this.renderSpanBar(l)).join('');
|
|
270
|
+
const allDayBars = allDayLayouts.map((l) => this.renderSpanBar(l)).join('');
|
|
281
271
|
const hourLabels = Array.from({ length: 24 }, (_, h) => {
|
|
282
272
|
const label = h === 0 ? '' : `${String(h).padStart(2, '0')}:00`;
|
|
283
273
|
return `<div class="cal__time-slot">${label}</div>`;
|
|
284
274
|
}).join('');
|
|
285
|
-
const dayCols = days
|
|
275
|
+
const dayCols = days
|
|
276
|
+
.map((d) => {
|
|
286
277
|
const timedEvents = CalendarLogic.getTimedEvents(events, d);
|
|
287
278
|
const hourCells = Array.from({ length: 24 }, () => `<div class="cal__day-col-hour"></div>`).join('');
|
|
288
279
|
const layouts = CalendarLogic.computeTimedLayout(timedEvents, d);
|
|
289
|
-
const eventOverlays = layouts
|
|
280
|
+
const eventOverlays = layouts
|
|
281
|
+
.map(({ event, top, height, col, cols }) => {
|
|
290
282
|
const cls = event.className ?? '';
|
|
291
283
|
let posStyle = `top:${top.toFixed(2)}%;height:${height.toFixed(2)}%`;
|
|
292
284
|
if (cols > 1) {
|
|
293
|
-
const l = (col / cols * 100).toFixed(2);
|
|
285
|
+
const l = ((col / cols) * 100).toFixed(2);
|
|
294
286
|
const w = (100 / cols).toFixed(2);
|
|
295
287
|
posStyle += `;left:calc(${l}% + 2px);right:auto;width:calc(${w}% - 4px)`;
|
|
296
288
|
}
|
|
@@ -300,12 +292,12 @@ class CalendarRenderer {
|
|
|
300
292
|
<span class="cal__event-time">${CalendarLogic.formatTime(event.start)}</span>
|
|
301
293
|
${event.title}
|
|
302
294
|
</div>`;
|
|
303
|
-
})
|
|
295
|
+
})
|
|
296
|
+
.join('');
|
|
304
297
|
return `<div class="cal__day-col" data-date="${d.toISOString()}">${hourCells}${eventOverlays}</div>`;
|
|
305
|
-
})
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
: '';
|
|
298
|
+
})
|
|
299
|
+
.join('');
|
|
300
|
+
const nowLine = showNowLine ? `<div class="cal__now-line" style="top:${CalendarLogic.nowLinePct().toFixed(3)}%"></div>` : '';
|
|
309
301
|
return `<div class="cal__week" role="grid">
|
|
310
302
|
<div class="cal__week-head">
|
|
311
303
|
<div class="cal__week-head-time"></div>
|
|
@@ -333,7 +325,7 @@ class CalendarRenderer {
|
|
|
333
325
|
for (let d = 1; d <= daysInMonth; d++) {
|
|
334
326
|
const day = new Date(year, month, d);
|
|
335
327
|
const dayEvents = CalendarLogic.getEventsForDay(events, day);
|
|
336
|
-
const filtered = dayEvents.filter(e => {
|
|
328
|
+
const filtered = dayEvents.filter((e) => {
|
|
337
329
|
if (!CalendarLogic.isMultiDay(e))
|
|
338
330
|
return true;
|
|
339
331
|
if (shownMultiDay.has(e.id))
|
|
@@ -351,7 +343,8 @@ class CalendarRenderer {
|
|
|
351
343
|
<span class="cal__agenda-num ${isToday ? 'is-today' : ''}">${d}</span>
|
|
352
344
|
</div>
|
|
353
345
|
<div class="cal__agenda-events">
|
|
354
|
-
${filtered
|
|
346
|
+
${filtered
|
|
347
|
+
.map((e) => {
|
|
355
348
|
const isMulti = CalendarLogic.isMultiDay(e);
|
|
356
349
|
let timeLabel;
|
|
357
350
|
if (isMulti) {
|
|
@@ -368,7 +361,8 @@ class CalendarRenderer {
|
|
|
368
361
|
<span class="cal__agenda-event-time">${timeLabel}</span>
|
|
369
362
|
<span class="cal__agenda-event-title">${e.title}</span>
|
|
370
363
|
</div>`;
|
|
371
|
-
})
|
|
364
|
+
})
|
|
365
|
+
.join('')}
|
|
372
366
|
</div>
|
|
373
367
|
</div>`;
|
|
374
368
|
}
|
|
@@ -386,6 +380,7 @@ class Calendar {
|
|
|
386
380
|
currentView;
|
|
387
381
|
events = [];
|
|
388
382
|
nowLineTimer = null;
|
|
383
|
+
listeners = new ListenerGroup();
|
|
389
384
|
constructor(options) {
|
|
390
385
|
if (typeof options.container === 'string') {
|
|
391
386
|
const el = document.querySelector(options.container);
|
|
@@ -451,7 +446,7 @@ class Calendar {
|
|
|
451
446
|
this.render();
|
|
452
447
|
}
|
|
453
448
|
removeEvent(id) {
|
|
454
|
-
this.events = this.events.filter(e => e.id !== id);
|
|
449
|
+
this.events = this.events.filter((e) => e.id !== id);
|
|
455
450
|
this.render();
|
|
456
451
|
}
|
|
457
452
|
setEvents(events) {
|
|
@@ -463,26 +458,24 @@ class Calendar {
|
|
|
463
458
|
}
|
|
464
459
|
destroy() {
|
|
465
460
|
this.clearNowLineTimer();
|
|
466
|
-
this.
|
|
467
|
-
this.container.removeEventListener('keydown', this.boundHandleKeydown);
|
|
461
|
+
this.listeners.destroy();
|
|
468
462
|
this.container.innerHTML = '';
|
|
469
463
|
this.container.removeAttribute('data-cal');
|
|
470
464
|
}
|
|
471
|
-
getTitle() {
|
|
465
|
+
getTitle(weekDays) {
|
|
472
466
|
const { monthNames } = this.locale;
|
|
473
467
|
const y = this.currentDate.getFullYear();
|
|
474
468
|
const m = this.currentDate.getMonth();
|
|
475
|
-
if (this.currentView === 'week') {
|
|
476
|
-
const
|
|
477
|
-
const
|
|
478
|
-
const last = days[6];
|
|
469
|
+
if (this.currentView === 'week' && weekDays) {
|
|
470
|
+
const first = weekDays[0];
|
|
471
|
+
const last = weekDays[6];
|
|
479
472
|
return first.getMonth() === last.getMonth()
|
|
480
473
|
? `${monthNames[first.getMonth()]} ${y}`
|
|
481
474
|
: `${monthNames[first.getMonth()]} – ${monthNames[last.getMonth()]} ${y}`;
|
|
482
475
|
}
|
|
483
476
|
return `${monthNames[m]} ${y}`;
|
|
484
477
|
}
|
|
485
|
-
buildHeader() {
|
|
478
|
+
buildHeader(weekDays) {
|
|
486
479
|
const v = this.currentView;
|
|
487
480
|
return `<div class="cal__header">
|
|
488
481
|
<div class="cal__nav">
|
|
@@ -494,7 +487,7 @@ class Calendar {
|
|
|
494
487
|
<svg class="icon-svg" aria-hidden="true"><use href="${this.options.iconBasePath}icons.svg#chevron_right"/></svg>
|
|
495
488
|
</button>
|
|
496
489
|
</div>
|
|
497
|
-
<h2 class="cal__title" aria-live="polite">${this.getTitle()}</h2>
|
|
490
|
+
<h2 class="cal__title" aria-live="polite">${this.getTitle(weekDays)}</h2>
|
|
498
491
|
<div class="cal__view-toggle" role="group" aria-label="Ansicht wählen">
|
|
499
492
|
<button class="cal__btn ${v === 'month' ? 'cal__btn--active' : ''}" data-action="view-month" aria-pressed="${v === 'month'}">${this.locale.month}</button>
|
|
500
493
|
<button class="cal__btn ${v === 'week' ? 'cal__btn--active' : ''}" data-action="view-week" aria-pressed="${v === 'week'}">${this.locale.week}</button>
|
|
@@ -502,7 +495,7 @@ class Calendar {
|
|
|
502
495
|
</div>
|
|
503
496
|
</div>`;
|
|
504
497
|
}
|
|
505
|
-
buildBody() {
|
|
498
|
+
buildBody(weekDays) {
|
|
506
499
|
const { firstDayOfWeek } = this.locale;
|
|
507
500
|
const y = this.currentDate.getFullYear();
|
|
508
501
|
const m = this.currentDate.getMonth();
|
|
@@ -510,8 +503,7 @@ class Calendar {
|
|
|
510
503
|
case 'month':
|
|
511
504
|
return this.renderer.renderMonthView(y, m, this.events, this.options.showOutsideDays, firstDayOfWeek);
|
|
512
505
|
case 'week': {
|
|
513
|
-
const
|
|
514
|
-
const showNowLine = weekDays.some(d => CalendarLogic.isToday(d));
|
|
506
|
+
const showNowLine = weekDays?.some((d) => CalendarLogic.isToday(d)) ?? false;
|
|
515
507
|
return this.renderer.renderWeekView(this.currentDate, this.events, firstDayOfWeek, showNowLine);
|
|
516
508
|
}
|
|
517
509
|
case 'agenda':
|
|
@@ -520,18 +512,16 @@ class Calendar {
|
|
|
520
512
|
}
|
|
521
513
|
render() {
|
|
522
514
|
this.clearNowLineTimer();
|
|
515
|
+
const weekDays = this.currentView === 'week' ? CalendarLogic.getWeekDays(this.currentDate, this.locale.firstDayOfWeek) : null;
|
|
523
516
|
const rootClass = ['cal', this.options.className].filter(Boolean).join(' ');
|
|
524
517
|
this.container.setAttribute('data-cal', this.currentView);
|
|
525
518
|
this.container.innerHTML = `<div class="${rootClass}" role="application" aria-label="Kalender">
|
|
526
|
-
${this.buildHeader()}
|
|
527
|
-
<div class="cal__body">${this.buildBody()}</div>
|
|
519
|
+
${this.buildHeader(weekDays)}
|
|
520
|
+
<div class="cal__body">${this.buildBody(weekDays)}</div>
|
|
528
521
|
</div>`;
|
|
529
|
-
if (
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
this.scrollToNow();
|
|
533
|
-
this.startNowLineTimer();
|
|
534
|
-
}
|
|
522
|
+
if (weekDays?.some((d) => CalendarLogic.isToday(d))) {
|
|
523
|
+
this.scrollToNow();
|
|
524
|
+
this.startNowLineTimer();
|
|
535
525
|
}
|
|
536
526
|
}
|
|
537
527
|
scrollToNow() {
|
|
@@ -554,11 +544,10 @@ class Calendar {
|
|
|
554
544
|
this.nowLineTimer = null;
|
|
555
545
|
}
|
|
556
546
|
}
|
|
557
|
-
boundHandleClick = (e) => this.handleClick(e);
|
|
558
|
-
boundHandleKeydown = (e) => this.handleKeydown(e);
|
|
559
547
|
attachEvents() {
|
|
560
|
-
this.
|
|
561
|
-
this.container.addEventListener('
|
|
548
|
+
const sig = { signal: this.listeners.signal };
|
|
549
|
+
this.container.addEventListener('click', (e) => this.handleClick(e), sig);
|
|
550
|
+
this.container.addEventListener('keydown', (e) => this.handleKeydown(e), sig);
|
|
562
551
|
}
|
|
563
552
|
handleClick(e) {
|
|
564
553
|
const target = e.target;
|
|
@@ -582,13 +571,17 @@ class Calendar {
|
|
|
582
571
|
const eventEl = target.closest('[data-event-id]');
|
|
583
572
|
if (eventEl) {
|
|
584
573
|
const id = eventEl.dataset.eventId;
|
|
585
|
-
const event = this.events.find(ev => ev.id === id);
|
|
574
|
+
const event = this.events.find((ev) => ev.id === id);
|
|
586
575
|
if (event) {
|
|
587
576
|
e.stopPropagation();
|
|
588
577
|
this.options.onEventClick(event);
|
|
589
578
|
}
|
|
590
579
|
return;
|
|
591
580
|
}
|
|
581
|
+
const dayEl = target.closest('.cal__day[data-date]');
|
|
582
|
+
if (dayEl) {
|
|
583
|
+
this.options.onDayClick(new Date(dayEl.dataset.date));
|
|
584
|
+
}
|
|
592
585
|
}
|
|
593
586
|
handleKeydown(e) {
|
|
594
587
|
const target = e.target;
|
package/js/carousel.d.ts
CHANGED
package/js/carousel.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ListenerGroup } from './listeners.js';
|
|
1
2
|
class Carousel {
|
|
2
3
|
root;
|
|
3
4
|
options;
|
|
@@ -10,15 +11,13 @@ class Carousel {
|
|
|
10
11
|
dotsNav;
|
|
11
12
|
dots;
|
|
12
13
|
autoPlayTimer = null;
|
|
13
|
-
|
|
14
|
+
listeners = new ListenerGroup();
|
|
14
15
|
constructor(elementOrSelector, options = {}) {
|
|
15
|
-
const element = typeof elementOrSelector === 'string'
|
|
16
|
-
? document.querySelector(elementOrSelector)
|
|
17
|
-
: elementOrSelector;
|
|
16
|
+
const element = typeof elementOrSelector === 'string' ? document.querySelector(elementOrSelector) : elementOrSelector;
|
|
18
17
|
this.options = {
|
|
19
18
|
loop: options.loop ?? false,
|
|
20
19
|
autoPlay: options.autoPlay ?? false,
|
|
21
|
-
autoPlayInterval: options.autoPlayInterval ?? 3000
|
|
20
|
+
autoPlayInterval: options.autoPlayInterval ?? 3000,
|
|
22
21
|
};
|
|
23
22
|
if (!element) {
|
|
24
23
|
throw new Error(`Carousel: Element not found for selector "${elementOrSelector}"`);
|
|
@@ -29,6 +28,9 @@ class Carousel {
|
|
|
29
28
|
init() {
|
|
30
29
|
this.setupDOM();
|
|
31
30
|
this.slides = Array.from(this.track.children);
|
|
31
|
+
if (this.slides.length === 0) {
|
|
32
|
+
throw new Error('Carousel: no slide elements found.');
|
|
33
|
+
}
|
|
32
34
|
this.slideWidth = this.slides[0].getBoundingClientRect().width;
|
|
33
35
|
this.currentIndex = 0;
|
|
34
36
|
this.bindEvents();
|
|
@@ -43,7 +45,7 @@ class Carousel {
|
|
|
43
45
|
container.classList.add('carousel-track-container');
|
|
44
46
|
this.track = document.createElement('ul');
|
|
45
47
|
this.track.classList.add('carousel-track');
|
|
46
|
-
slides.forEach(slide => {
|
|
48
|
+
slides.forEach((slide) => {
|
|
47
49
|
slide.classList.add('carousel-slide');
|
|
48
50
|
this.track.appendChild(slide);
|
|
49
51
|
});
|
|
@@ -73,19 +75,25 @@ class Carousel {
|
|
|
73
75
|
this.root.setAttribute('tabindex', '0');
|
|
74
76
|
}
|
|
75
77
|
bindEvents() {
|
|
76
|
-
const sig = { signal: this.
|
|
78
|
+
const sig = { signal: this.listeners.signal };
|
|
77
79
|
this.nextButton.addEventListener('click', () => this.moveToNextSlide(), sig);
|
|
78
80
|
this.prevButton.addEventListener('click', () => this.moveToPrevSlide(), sig);
|
|
79
81
|
this.dotsNav.addEventListener('click', (e) => {
|
|
80
82
|
const targetDot = e.target.closest('button');
|
|
81
83
|
if (!targetDot)
|
|
82
84
|
return;
|
|
83
|
-
const targetIndex = this.dots.findIndex(dot => dot === targetDot);
|
|
85
|
+
const targetIndex = this.dots.findIndex((dot) => dot === targetDot);
|
|
84
86
|
this.moveToSlide(targetIndex);
|
|
85
87
|
}, sig);
|
|
88
|
+
let resizeTimer = null;
|
|
86
89
|
window.addEventListener('resize', () => {
|
|
87
|
-
|
|
88
|
-
|
|
90
|
+
if (resizeTimer !== null)
|
|
91
|
+
clearTimeout(resizeTimer);
|
|
92
|
+
resizeTimer = setTimeout(() => {
|
|
93
|
+
this.slideWidth = this.slides[0].getBoundingClientRect().width;
|
|
94
|
+
this.moveToSlide(this.currentIndex, false);
|
|
95
|
+
resizeTimer = null;
|
|
96
|
+
}, 100);
|
|
89
97
|
}, sig);
|
|
90
98
|
this.root.addEventListener('keydown', (e) => {
|
|
91
99
|
if (e.key === 'ArrowLeft')
|
|
@@ -134,17 +142,17 @@ class Carousel {
|
|
|
134
142
|
this.moveToSlide(this.currentIndex - 1);
|
|
135
143
|
}
|
|
136
144
|
updateDots(targetIndex) {
|
|
137
|
-
this.dots.forEach(dot => dot.classList.remove('current-slide'));
|
|
145
|
+
this.dots.forEach((dot) => dot.classList.remove('current-slide'));
|
|
138
146
|
this.dots[targetIndex].classList.add('current-slide');
|
|
139
147
|
}
|
|
140
148
|
addTouchSupport() {
|
|
141
149
|
let startX = 0;
|
|
142
150
|
let isDragging = false;
|
|
143
|
-
const sig = { signal: this.
|
|
151
|
+
const sig = { signal: this.listeners.signal };
|
|
144
152
|
this.track.addEventListener('touchstart', (e) => {
|
|
145
153
|
startX = e.touches[0].clientX;
|
|
146
154
|
isDragging = true;
|
|
147
|
-
}, { passive: true
|
|
155
|
+
}, { ...sig, passive: true });
|
|
148
156
|
this.track.addEventListener('touchend', (e) => {
|
|
149
157
|
if (!isDragging)
|
|
150
158
|
return;
|
|
@@ -177,7 +185,7 @@ class Carousel {
|
|
|
177
185
|
}
|
|
178
186
|
destroy() {
|
|
179
187
|
this.pauseAutoPlay();
|
|
180
|
-
this.
|
|
188
|
+
this.listeners.destroy();
|
|
181
189
|
}
|
|
182
190
|
}
|
|
183
191
|
export { Carousel };
|
package/js/chart.d.ts
CHANGED