@dodlhuat/basix 1.3.2 → 1.3.4
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 +13 -7
- package/css/accordion.scss +0 -5
- package/css/badge.scss +9 -6
- package/css/bottom-sheet.scss +3 -8
- package/css/breadcrumb.scss +6 -15
- package/css/button.scss +63 -16
- package/css/calendar.scss +0 -54
- package/css/card.scss +0 -5
- package/css/carousel.scss +0 -3
- package/css/chart.scss +0 -25
- package/css/chat-bubbles.scss +0 -15
- package/css/checkbox.scss +3 -2
- package/css/chips.scss +13 -7
- package/css/code-viewer.scss +1 -5
- package/css/colors.scss +4 -0
- package/css/context-menu.scss +4 -6
- package/css/datepicker.scss +4 -7
- package/css/docs.scss +0 -8
- package/css/dropdown.scss +15 -1
- package/css/editor.scss +1 -23
- package/css/file-uploader.scss +2 -2
- package/css/flyout-menu.scss +66 -44
- package/css/form.scss +0 -28
- package/css/gallery.scss +2 -3
- package/css/group-picker.scss +5 -35
- package/css/icons.scss +0 -3
- package/css/lightbox.scss +2 -4
- package/css/mixins.scss +8 -0
- package/css/modal.scss +24 -3
- package/css/parameters.scss +6 -1
- package/css/popover.scss +3 -15
- package/css/progress.scss +0 -6
- package/css/push-menu.scss +3 -28
- package/css/radiobutton.scss +2 -1
- package/css/range-slider.scss +1 -7
- package/css/scrollbar.scss +2 -6
- package/css/sidebar-nav.scss +24 -11
- package/css/stepper.scss +0 -4
- package/css/style.css +287 -89
- package/css/style.css.map +1 -1
- package/css/style.min.css +1 -1
- package/css/style.min.css.map +1 -1
- package/css/style.scss +1 -1
- package/css/table.scss +0 -4
- package/css/tabs.scss +49 -2
- package/css/timeline.scss +1 -13
- package/css/timepicker.scss +6 -7
- package/css/toast.scss +1 -1
- package/css/tooltip.scss +1 -5
- package/css/tree.scss +1 -1
- package/css/typography.scss +38 -9
- package/css/virtual-dropdown.scss +3 -28
- package/js/bottom-sheet.d.ts +3 -1
- package/js/bottom-sheet.js +26 -27
- package/js/calendar.d.ts +7 -0
- package/js/calendar.js +14 -33
- package/js/carousel.d.ts +2 -0
- package/js/carousel.js +13 -5
- package/js/chart.d.ts +4 -0
- package/js/chart.js +13 -31
- package/js/code-viewer.d.ts +1 -0
- package/js/code-viewer.js +4 -0
- package/js/context-menu.d.ts +9 -2
- package/js/context-menu.js +17 -14
- package/js/datepicker.d.ts +4 -0
- package/js/datepicker.js +26 -11
- package/js/dropdown.d.ts +4 -3
- package/js/dropdown.js +17 -9
- package/js/editor.d.ts +1 -0
- package/js/editor.js +9 -3
- package/js/file-uploader.d.ts +4 -0
- package/js/file-uploader.js +52 -43
- package/js/flyout-menu.d.ts +5 -3
- package/js/flyout-menu.js +23 -46
- package/js/gallery.d.ts +5 -0
- package/js/gallery.js +44 -26
- package/js/group-picker.d.ts +5 -0
- package/js/group-picker.js +12 -17
- package/js/lightbox.d.ts +3 -0
- package/js/lightbox.js +12 -6
- package/js/modal.d.ts +3 -1
- package/js/modal.js +15 -12
- package/js/popover.d.ts +2 -0
- package/js/popover.js +26 -30
- package/js/position.d.ts +2 -0
- package/js/position.js +1 -5
- package/js/push-menu.d.ts +2 -0
- package/js/push-menu.js +22 -35
- package/js/range-slider.d.ts +1 -0
- package/js/range-slider.js +5 -3
- package/js/scroll.d.ts +2 -0
- package/js/scroll.js +1 -0
- package/js/scrollbar.d.ts +2 -0
- package/js/scrollbar.js +24 -36
- package/js/select.d.ts +1 -0
- package/js/select.js +5 -10
- package/js/sidebar-nav.d.ts +12 -0
- package/js/sidebar-nav.js +47 -0
- package/js/stepper.d.ts +2 -0
- package/js/stepper.js +7 -1
- package/js/table.d.ts +4 -0
- package/js/table.js +15 -22
- package/js/tabs.d.ts +2 -0
- package/js/tabs.js +6 -14
- package/js/theme.d.ts +1 -0
- package/js/theme.js +5 -13
- package/js/timepicker.d.ts +3 -0
- package/js/timepicker.js +81 -67
- package/js/toast.d.ts +3 -0
- package/js/toast.js +24 -15
- package/js/tooltip.d.ts +2 -0
- package/js/tooltip.js +21 -19
- package/js/tree.d.ts +3 -0
- package/js/tree.js +13 -0
- package/js/utils.d.ts +1 -3
- package/js/utils.js +0 -3
- package/js/virtual-dropdown.d.ts +3 -0
- package/js/virtual-dropdown.js +25 -0
- package/package.json +2 -2
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
@use "parameters" as *;
|
|
2
1
|
@use "properties";
|
|
2
|
+
@use "parameters" as *;
|
|
3
3
|
|
|
4
|
-
// Flip-above fallback: used when there isn't enough space below the trigger.
|
|
5
|
-
// The browser tries this when the default (below) position overflows the viewport.
|
|
6
4
|
@position-try --vd-above {
|
|
7
5
|
top: auto;
|
|
8
6
|
bottom: anchor(top);
|
|
@@ -10,15 +8,12 @@
|
|
|
10
8
|
margin-bottom: 6px;
|
|
11
9
|
}
|
|
12
10
|
|
|
13
|
-
// All selectors scoped under .custom-dropdown to avoid conflicts with dropdown.scss
|
|
14
11
|
.custom-dropdown {
|
|
15
12
|
position: relative;
|
|
16
13
|
width: 100%;
|
|
17
14
|
user-select: none;
|
|
18
15
|
display: inline-block;
|
|
19
16
|
|
|
20
|
-
// ── Trigger ──────────────────────────────────────────────────────────
|
|
21
|
-
|
|
22
17
|
.dropdown-trigger {
|
|
23
18
|
background: var(--background);
|
|
24
19
|
border: 1.5px solid var(--divider);
|
|
@@ -87,22 +82,13 @@
|
|
|
87
82
|
transform: rotate(180deg);
|
|
88
83
|
}
|
|
89
84
|
|
|
90
|
-
// ── Menu ─────────────────────────────────────────────────────────────
|
|
91
|
-
//
|
|
92
|
-
// The menu is a popover (top-layer) element. Anchor positioning places it
|
|
93
|
-
// below the trigger and automatically flips above when there isn't room.
|
|
94
|
-
//
|
|
95
|
-
// anchor-name / position-anchor are unique per instance and set as inline
|
|
96
|
-
// styles by VirtualDropdown so multiple instances don't conflict.
|
|
97
|
-
|
|
98
85
|
.dropdown-menu {
|
|
99
|
-
|
|
86
|
+
|
|
100
87
|
inset: unset;
|
|
101
88
|
margin: 0;
|
|
102
89
|
padding: 0;
|
|
103
90
|
border: none;
|
|
104
91
|
|
|
105
|
-
// Anchor positioning: default = below trigger, fallback = above
|
|
106
92
|
position: fixed;
|
|
107
93
|
top: anchor(bottom);
|
|
108
94
|
left: anchor(left);
|
|
@@ -110,7 +96,6 @@
|
|
|
110
96
|
margin-top: 6px;
|
|
111
97
|
position-try-fallbacks: --vd-above;
|
|
112
98
|
|
|
113
|
-
// Appearance
|
|
114
99
|
background: var(--background);
|
|
115
100
|
border: 1.5px solid var(--divider);
|
|
116
101
|
border-radius: calc($border-radius * 1.5);
|
|
@@ -119,10 +104,6 @@
|
|
|
119
104
|
0 2px 8px rgba(0, 0, 0, 0.06);
|
|
120
105
|
transform-origin: top center;
|
|
121
106
|
|
|
122
|
-
// Entry / exit animation.
|
|
123
|
-
// Closed state = exit target (browser transitions to this on close).
|
|
124
|
-
// @starting-style defines the entry start point (same values, so it
|
|
125
|
-
// fades/slides in from the same position it would exit to).
|
|
126
107
|
opacity: 0;
|
|
127
108
|
transform: translateY(-6px) scale(0.975);
|
|
128
109
|
|
|
@@ -143,8 +124,6 @@
|
|
|
143
124
|
}
|
|
144
125
|
}
|
|
145
126
|
|
|
146
|
-
// ── Search ───────────────────────────────────────────────────────────
|
|
147
|
-
|
|
148
127
|
.dropdown-search {
|
|
149
128
|
padding: calc($spacing * 0.4);
|
|
150
129
|
border-bottom: 1.5px solid var(--divider);
|
|
@@ -179,8 +158,6 @@
|
|
|
179
158
|
}
|
|
180
159
|
}
|
|
181
160
|
|
|
182
|
-
// ── Virtual list ─────────────────────────────────────────────────────
|
|
183
|
-
|
|
184
161
|
.dropdown-list-wrapper {
|
|
185
162
|
max-height: 250px;
|
|
186
163
|
overflow-y: auto;
|
|
@@ -200,8 +177,6 @@
|
|
|
200
177
|
width: 100%;
|
|
201
178
|
}
|
|
202
179
|
|
|
203
|
-
// ── Items ─────────────────────────────────────────────────────────────
|
|
204
|
-
|
|
205
180
|
.dropdown-item {
|
|
206
181
|
padding: 0 calc($spacing * 0.65);
|
|
207
182
|
cursor: pointer;
|
|
@@ -237,7 +212,7 @@
|
|
|
237
212
|
padding: 0;
|
|
238
213
|
box-shadow: none;
|
|
239
214
|
border: 1.5px solid var(--divider);
|
|
240
|
-
border-radius:
|
|
215
|
+
border-radius: $radius-sm;
|
|
241
216
|
background: var(--background);
|
|
242
217
|
margin-right: calc($spacing * 0.6);
|
|
243
218
|
pointer-events: none;
|
package/js/bottom-sheet.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** Options for configuring a BottomSheet instance. */
|
|
1
2
|
interface BottomSheetOptions {
|
|
2
3
|
content: string;
|
|
3
4
|
header?: string;
|
|
@@ -6,6 +7,7 @@ interface BottomSheetOptions {
|
|
|
6
7
|
snapHeight?: 'auto' | 'half' | 'full';
|
|
7
8
|
onClose?: () => void;
|
|
8
9
|
}
|
|
10
|
+
/** Slide-up sheet that attaches to the bottom of the viewport. */
|
|
9
11
|
declare class BottomSheet {
|
|
10
12
|
private readonly content;
|
|
11
13
|
private readonly header?;
|
|
@@ -22,7 +24,7 @@ declare class BottomSheet {
|
|
|
22
24
|
private isDragging;
|
|
23
25
|
constructor(options: BottomSheetOptions);
|
|
24
26
|
show(): void;
|
|
25
|
-
hide()
|
|
27
|
+
hide: () => void;
|
|
26
28
|
snapTo(height: 'auto' | 'half' | 'full'): void;
|
|
27
29
|
private handleEscape;
|
|
28
30
|
private handleBackdropClick;
|
package/js/bottom-sheet.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
import { sanitizeHtml } from './utils.js';
|
|
2
|
+
/** Slide-up sheet that attaches to the bottom of the viewport. */
|
|
2
3
|
class BottomSheet {
|
|
4
|
+
content;
|
|
5
|
+
header;
|
|
6
|
+
footer;
|
|
7
|
+
closeable;
|
|
8
|
+
snapHeight;
|
|
9
|
+
onClose;
|
|
10
|
+
wrapper = null;
|
|
11
|
+
sheet = null;
|
|
12
|
+
handle = null;
|
|
13
|
+
body = null;
|
|
14
|
+
dragStartY = 0;
|
|
15
|
+
currentDragY = 0;
|
|
16
|
+
isDragging = false;
|
|
3
17
|
constructor(options) {
|
|
4
|
-
this.wrapper = null;
|
|
5
|
-
this.sheet = null;
|
|
6
|
-
this.handle = null;
|
|
7
|
-
this.body = null;
|
|
8
|
-
// Touch drag state
|
|
9
|
-
this.dragStartY = 0;
|
|
10
|
-
this.currentDragY = 0;
|
|
11
|
-
this.isDragging = false;
|
|
12
18
|
this.content = options.content;
|
|
13
19
|
this.header = options.header;
|
|
14
20
|
this.footer = options.footer;
|
|
15
21
|
this.closeable = options.closeable ?? true;
|
|
16
22
|
this.snapHeight = options.snapHeight ?? 'auto';
|
|
17
23
|
this.onClose = options.onClose;
|
|
18
|
-
this.hide = this.hide.bind(this);
|
|
19
|
-
this.handleEscape = this.handleEscape.bind(this);
|
|
20
|
-
this.handleBackdropClick = this.handleBackdropClick.bind(this);
|
|
21
|
-
this.handleTouchStart = this.handleTouchStart.bind(this);
|
|
22
|
-
this.handleTouchMove = this.handleTouchMove.bind(this);
|
|
23
|
-
this.handleTouchEnd = this.handleTouchEnd.bind(this);
|
|
24
24
|
}
|
|
25
25
|
show() {
|
|
26
26
|
this.hide();
|
|
@@ -53,7 +53,7 @@ class BottomSheet {
|
|
|
53
53
|
wrapper.classList.add('is-visible');
|
|
54
54
|
});
|
|
55
55
|
}
|
|
56
|
-
hide() {
|
|
56
|
+
hide = () => {
|
|
57
57
|
if (!this.wrapper)
|
|
58
58
|
return;
|
|
59
59
|
const backdrop = this.wrapper.querySelector('.bottom-sheet-backdrop');
|
|
@@ -75,7 +75,7 @@ class BottomSheet {
|
|
|
75
75
|
wrapper.remove();
|
|
76
76
|
this.onClose?.();
|
|
77
77
|
}, 420);
|
|
78
|
-
}
|
|
78
|
+
};
|
|
79
79
|
snapTo(height) {
|
|
80
80
|
if (!this.sheet)
|
|
81
81
|
return;
|
|
@@ -85,24 +85,24 @@ class BottomSheet {
|
|
|
85
85
|
this.sheet.classList.add(`snap-${height}`);
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
|
-
handleEscape(e) {
|
|
88
|
+
handleEscape = (e) => {
|
|
89
89
|
if (e.key === 'Escape')
|
|
90
90
|
this.hide();
|
|
91
|
-
}
|
|
92
|
-
handleBackdropClick(e) {
|
|
91
|
+
};
|
|
92
|
+
handleBackdropClick = (e) => {
|
|
93
93
|
if (e.target?.classList.contains('bottom-sheet-backdrop')) {
|
|
94
94
|
this.hide();
|
|
95
95
|
}
|
|
96
|
-
}
|
|
97
|
-
handleTouchStart(e) {
|
|
96
|
+
};
|
|
97
|
+
handleTouchStart = (e) => {
|
|
98
98
|
this.dragStartY = e.touches[0].clientY;
|
|
99
99
|
this.currentDragY = 0;
|
|
100
100
|
this.isDragging = true;
|
|
101
101
|
if (this.sheet) {
|
|
102
102
|
this.sheet.style.transition = 'none';
|
|
103
103
|
}
|
|
104
|
-
}
|
|
105
|
-
handleTouchMove(e) {
|
|
104
|
+
};
|
|
105
|
+
handleTouchMove = (e) => {
|
|
106
106
|
if (!this.isDragging || !this.sheet)
|
|
107
107
|
return;
|
|
108
108
|
const deltaY = e.touches[0].clientY - this.dragStartY;
|
|
@@ -118,8 +118,8 @@ class BottomSheet {
|
|
|
118
118
|
const translateX = isDesktop ? '-50%' : '0';
|
|
119
119
|
this.sheet.style.transform = `translateX(${translateX}) translateY(${this.currentDragY}px)`;
|
|
120
120
|
e.preventDefault();
|
|
121
|
-
}
|
|
122
|
-
handleTouchEnd() {
|
|
121
|
+
};
|
|
122
|
+
handleTouchEnd = () => {
|
|
123
123
|
if (!this.isDragging || !this.sheet)
|
|
124
124
|
return;
|
|
125
125
|
this.isDragging = false;
|
|
@@ -128,11 +128,10 @@ class BottomSheet {
|
|
|
128
128
|
this.hide();
|
|
129
129
|
}
|
|
130
130
|
else {
|
|
131
|
-
// Spring back
|
|
132
131
|
this.sheet.style.transition = '';
|
|
133
132
|
this.sheet.style.transform = '';
|
|
134
133
|
}
|
|
135
|
-
}
|
|
134
|
+
};
|
|
136
135
|
updateScrollMask() {
|
|
137
136
|
if (!this.body)
|
|
138
137
|
return;
|
package/js/calendar.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** Represents a single calendar event with a start/end date. */
|
|
1
2
|
export interface CalendarEvent {
|
|
2
3
|
id: string;
|
|
3
4
|
title: string;
|
|
@@ -7,6 +8,7 @@ export interface CalendarEvent {
|
|
|
7
8
|
className?: string;
|
|
8
9
|
}
|
|
9
10
|
export type CalendarView = 'month' | 'week' | 'agenda';
|
|
11
|
+
/** Localisation strings and week-start configuration for the Calendar. */
|
|
10
12
|
export interface CalendarLocale {
|
|
11
13
|
monthNames: string[];
|
|
12
14
|
dayNamesShort: string[];
|
|
@@ -19,6 +21,7 @@ export interface CalendarLocale {
|
|
|
19
21
|
allDay: string;
|
|
20
22
|
noEvents: string;
|
|
21
23
|
}
|
|
24
|
+
/** Configuration options for the Calendar component. */
|
|
22
25
|
export interface CalendarOptions {
|
|
23
26
|
container: HTMLElement | string;
|
|
24
27
|
events?: CalendarEvent[];
|
|
@@ -31,6 +34,7 @@ export interface CalendarOptions {
|
|
|
31
34
|
className?: string;
|
|
32
35
|
iconBasePath?: string;
|
|
33
36
|
}
|
|
37
|
+
/** Layout descriptor for a multi-day event spanning columns in a week row. */
|
|
34
38
|
interface SpanLayout {
|
|
35
39
|
event: CalendarEvent;
|
|
36
40
|
colStart: number;
|
|
@@ -39,6 +43,7 @@ interface SpanLayout {
|
|
|
39
43
|
continuesBefore: boolean;
|
|
40
44
|
continuesAfter: boolean;
|
|
41
45
|
}
|
|
46
|
+
/** Layout descriptor for a timed event positioned in a day column. */
|
|
42
47
|
interface TimedEventLayout {
|
|
43
48
|
event: CalendarEvent;
|
|
44
49
|
top: number;
|
|
@@ -68,6 +73,7 @@ export declare const CalendarLogic: {
|
|
|
68
73
|
computeTimedLayout(events: CalendarEvent[], day: Date): TimedEventLayout[];
|
|
69
74
|
nowLinePct(): number;
|
|
70
75
|
};
|
|
76
|
+
/** Produces HTML strings for each Calendar view (month, week, agenda). */
|
|
71
77
|
export declare class CalendarRenderer {
|
|
72
78
|
private locale;
|
|
73
79
|
constructor(locale: CalendarLocale);
|
|
@@ -80,6 +86,7 @@ export declare class CalendarRenderer {
|
|
|
80
86
|
renderWeekView(date: Date, events: CalendarEvent[], firstDayOfWeek: number, showNowLine?: boolean): string;
|
|
81
87
|
renderAgendaView(year: number, month: number, events: CalendarEvent[]): string;
|
|
82
88
|
}
|
|
89
|
+
/** Main Calendar controller — manages state, rendering, and event delegation. */
|
|
83
90
|
export declare class Calendar {
|
|
84
91
|
private container;
|
|
85
92
|
private options;
|
package/js/calendar.js
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// calendar.ts — Basix Calendar Component
|
|
3
|
-
// ============================================================
|
|
4
|
-
// -----------------------------------------------------------
|
|
5
|
-
// Date Logic
|
|
6
|
-
// -----------------------------------------------------------
|
|
7
1
|
export const CalendarLogic = {
|
|
8
2
|
getMonthGrid(year, month, firstDayOfWeek) {
|
|
9
3
|
const firstOfMonth = new Date(year, month, 1);
|
|
@@ -146,7 +140,6 @@ export const CalendarLogic = {
|
|
|
146
140
|
return diff;
|
|
147
141
|
return (b.end.getTime() - b.start.getTime()) - (a.end.getTime() - a.start.getTime());
|
|
148
142
|
});
|
|
149
|
-
// Greedy sub-column assignment
|
|
150
143
|
const colEnds = [];
|
|
151
144
|
const assigns = [];
|
|
152
145
|
for (const event of sorted) {
|
|
@@ -160,7 +153,6 @@ export const CalendarLogic = {
|
|
|
160
153
|
assigns.push({ event, col });
|
|
161
154
|
}
|
|
162
155
|
return assigns.map(({ event, col }) => {
|
|
163
|
-
// cols = highest sub-column among events that overlap this one + 1
|
|
164
156
|
const cols = assigns
|
|
165
157
|
.filter(a => a.event.start < event.end && a.event.end > event.start)
|
|
166
158
|
.reduce((max, a) => Math.max(max, a.col), 0) + 1;
|
|
@@ -173,9 +165,6 @@ export const CalendarLogic = {
|
|
|
173
165
|
return (now.getHours() * 60 + now.getMinutes()) / 1440 * 100;
|
|
174
166
|
},
|
|
175
167
|
};
|
|
176
|
-
// -----------------------------------------------------------
|
|
177
|
-
// Default Locale
|
|
178
|
-
// -----------------------------------------------------------
|
|
179
168
|
const DEFAULT_LOCALE = {
|
|
180
169
|
monthNames: [
|
|
181
170
|
'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni',
|
|
@@ -191,10 +180,9 @@ const DEFAULT_LOCALE = {
|
|
|
191
180
|
allDay: 'Ganztägig',
|
|
192
181
|
noEvents: 'Keine Termine',
|
|
193
182
|
};
|
|
194
|
-
|
|
195
|
-
// Renderer
|
|
196
|
-
// -----------------------------------------------------------
|
|
183
|
+
/** Produces HTML strings for each Calendar view (month, week, agenda). */
|
|
197
184
|
export class CalendarRenderer {
|
|
185
|
+
locale;
|
|
198
186
|
constructor(locale) {
|
|
199
187
|
this.locale = locale;
|
|
200
188
|
}
|
|
@@ -288,7 +276,6 @@ export class CalendarRenderer {
|
|
|
288
276
|
const dow = this.locale.dayNamesShort[(d.getDay() + 7) % 7];
|
|
289
277
|
return `<div class="${cls}">${dow}<span>${d.getDate()}</span></div>`;
|
|
290
278
|
}).join('');
|
|
291
|
-
// All-day row: span layout for all allDay events (both single-day and multi-day)
|
|
292
279
|
const allDayEvents = events.filter(e => e.allDay);
|
|
293
280
|
const allDayLayouts = CalendarLogic.computeSpanLayout(days, allDayEvents);
|
|
294
281
|
const allDayLanes = allDayLayouts.length > 0 ? Math.max(...allDayLayouts.map(l => l.lane)) + 1 : 0;
|
|
@@ -349,7 +336,6 @@ export class CalendarRenderer {
|
|
|
349
336
|
for (let d = 1; d <= daysInMonth; d++) {
|
|
350
337
|
const day = new Date(year, month, d);
|
|
351
338
|
const dayEvents = CalendarLogic.getEventsForDay(events, day);
|
|
352
|
-
// Multi-day events show only once (first occurrence in this month)
|
|
353
339
|
const filtered = dayEvents.filter(e => {
|
|
354
340
|
if (!CalendarLogic.isMultiDay(e))
|
|
355
341
|
return true;
|
|
@@ -394,18 +380,17 @@ export class CalendarRenderer {
|
|
|
394
380
|
return `<div class="cal__agenda">${html}</div>`;
|
|
395
381
|
}
|
|
396
382
|
}
|
|
397
|
-
|
|
398
|
-
// Calendar — main controller
|
|
399
|
-
// -----------------------------------------------------------
|
|
383
|
+
/** Main Calendar controller — manages state, rendering, and event delegation. */
|
|
400
384
|
export class Calendar {
|
|
385
|
+
container;
|
|
386
|
+
options;
|
|
387
|
+
locale;
|
|
388
|
+
renderer;
|
|
389
|
+
currentDate;
|
|
390
|
+
currentView;
|
|
391
|
+
events = [];
|
|
392
|
+
nowLineTimer = null;
|
|
401
393
|
constructor(options) {
|
|
402
|
-
this.events = [];
|
|
403
|
-
this.nowLineTimer = null;
|
|
404
|
-
// ----------------------------------------------------------
|
|
405
|
-
// Event delegation
|
|
406
|
-
// ----------------------------------------------------------
|
|
407
|
-
this.boundHandleClick = (e) => this.handleClick(e);
|
|
408
|
-
this.boundHandleKeydown = (e) => this.handleKeydown(e);
|
|
409
394
|
if (typeof options.container === 'string') {
|
|
410
395
|
const el = document.querySelector(options.container);
|
|
411
396
|
if (!el)
|
|
@@ -435,9 +420,6 @@ export class Calendar {
|
|
|
435
420
|
this.render();
|
|
436
421
|
this.attachEvents();
|
|
437
422
|
}
|
|
438
|
-
// ----------------------------------------------------------
|
|
439
|
-
// Public API
|
|
440
|
-
// ----------------------------------------------------------
|
|
441
423
|
setView(view) {
|
|
442
424
|
this.currentView = view;
|
|
443
425
|
this.render();
|
|
@@ -490,9 +472,6 @@ export class Calendar {
|
|
|
490
472
|
this.container.innerHTML = '';
|
|
491
473
|
this.container.removeAttribute('data-cal');
|
|
492
474
|
}
|
|
493
|
-
// ----------------------------------------------------------
|
|
494
|
-
// Rendering
|
|
495
|
-
// ----------------------------------------------------------
|
|
496
475
|
getTitle() {
|
|
497
476
|
const { monthNames } = this.locale;
|
|
498
477
|
const y = this.currentDate.getFullYear();
|
|
@@ -571,7 +550,7 @@ export class Calendar {
|
|
|
571
550
|
const line = this.container.querySelector('.cal__now-line');
|
|
572
551
|
if (line)
|
|
573
552
|
line.style.top = `${CalendarLogic.nowLinePct().toFixed(3)}%`;
|
|
574
|
-
},
|
|
553
|
+
}, 60_000);
|
|
575
554
|
}
|
|
576
555
|
clearNowLineTimer() {
|
|
577
556
|
if (this.nowLineTimer !== null) {
|
|
@@ -579,6 +558,8 @@ export class Calendar {
|
|
|
579
558
|
this.nowLineTimer = null;
|
|
580
559
|
}
|
|
581
560
|
}
|
|
561
|
+
boundHandleClick = (e) => this.handleClick(e);
|
|
562
|
+
boundHandleKeydown = (e) => this.handleKeydown(e);
|
|
582
563
|
attachEvents() {
|
|
583
564
|
this.container.addEventListener('click', this.boundHandleClick);
|
|
584
565
|
this.container.addEventListener('keydown', this.boundHandleKeydown);
|
package/js/carousel.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
/** Options for configuring a Carousel instance. */
|
|
1
2
|
interface CarouselOptions {
|
|
2
3
|
loop?: boolean;
|
|
3
4
|
autoPlay?: boolean;
|
|
4
5
|
autoPlayInterval?: number;
|
|
5
6
|
}
|
|
7
|
+
/** Slide-based carousel with optional autoplay, loop, dot navigation, and touch support. */
|
|
6
8
|
declare class Carousel {
|
|
7
9
|
private root;
|
|
8
10
|
private options;
|
package/js/carousel.js
CHANGED
|
@@ -1,7 +1,18 @@
|
|
|
1
|
+
/** Slide-based carousel with optional autoplay, loop, dot navigation, and touch support. */
|
|
1
2
|
class Carousel {
|
|
3
|
+
root;
|
|
4
|
+
options;
|
|
5
|
+
track;
|
|
6
|
+
slides;
|
|
7
|
+
slideWidth;
|
|
8
|
+
currentIndex;
|
|
9
|
+
prevButton;
|
|
10
|
+
nextButton;
|
|
11
|
+
dotsNav;
|
|
12
|
+
dots;
|
|
13
|
+
autoPlayTimer = null;
|
|
14
|
+
abortController = new AbortController();
|
|
2
15
|
constructor(elementOrSelector, options = {}) {
|
|
3
|
-
this.autoPlayTimer = null;
|
|
4
|
-
this.abortController = new AbortController();
|
|
5
16
|
const element = typeof elementOrSelector === 'string'
|
|
6
17
|
? document.querySelector(elementOrSelector)
|
|
7
18
|
: elementOrSelector;
|
|
@@ -60,7 +71,6 @@ class Carousel {
|
|
|
60
71
|
this.dots.push(dot);
|
|
61
72
|
});
|
|
62
73
|
this.root.appendChild(this.dotsNav);
|
|
63
|
-
// Make focusable for keyboard nav
|
|
64
74
|
this.root.setAttribute('tabindex', '0');
|
|
65
75
|
}
|
|
66
76
|
bindEvents() {
|
|
@@ -78,14 +88,12 @@ class Carousel {
|
|
|
78
88
|
this.slideWidth = this.slides[0].getBoundingClientRect().width;
|
|
79
89
|
this.moveToSlide(this.currentIndex, false);
|
|
80
90
|
}, sig);
|
|
81
|
-
// Keyboard navigation
|
|
82
91
|
this.root.addEventListener('keydown', (e) => {
|
|
83
92
|
if (e.key === 'ArrowLeft')
|
|
84
93
|
this.moveToPrevSlide();
|
|
85
94
|
if (e.key === 'ArrowRight')
|
|
86
95
|
this.moveToNextSlide();
|
|
87
96
|
}, sig);
|
|
88
|
-
// Pause autoplay on hover / focus
|
|
89
97
|
if (this.options.autoPlay) {
|
|
90
98
|
this.root.addEventListener('mouseenter', () => this.pauseAutoPlay(), sig);
|
|
91
99
|
this.root.addEventListener('mouseleave', () => this.resumeAutoPlay(), sig);
|
package/js/chart.d.ts
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
export type ChartType = 'line' | 'area' | 'column' | 'bar' | 'pie';
|
|
2
2
|
export type ChartCurve = 'smooth' | 'linear' | 'step';
|
|
3
|
+
/** A single labelled data value within a chart series. */
|
|
3
4
|
export interface ChartDataPoint {
|
|
4
5
|
label: string;
|
|
5
6
|
value: number;
|
|
6
7
|
}
|
|
8
|
+
/** A named data series with optional per-series colour override. */
|
|
7
9
|
export interface ChartSeries {
|
|
8
10
|
name: string;
|
|
9
11
|
data: ChartDataPoint[];
|
|
10
12
|
color?: string;
|
|
11
13
|
}
|
|
14
|
+
/** Configuration options for a Chart instance. */
|
|
12
15
|
export interface ChartOptions {
|
|
13
16
|
type: ChartType;
|
|
14
17
|
series: ChartSeries[];
|
|
@@ -27,6 +30,7 @@ export interface ChartOptions {
|
|
|
27
30
|
yMax?: number;
|
|
28
31
|
onPointClick?: (series: ChartSeries, point: ChartDataPoint, index: number) => void;
|
|
29
32
|
}
|
|
33
|
+
/** SVG-based chart component supporting line, area, column, bar, and pie types. */
|
|
30
34
|
declare class Chart {
|
|
31
35
|
private container;
|
|
32
36
|
private opts;
|