@dodlhuat/basix 1.2.0 → 1.2.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.
- package/README.md +56 -1
- package/css/accordion.scss +86 -87
- package/css/alert.scss +137 -137
- package/css/button.scss +48 -0
- package/css/calendar.scss +957 -0
- package/css/card.scss +65 -65
- package/css/chart.scss +270 -157
- package/css/chat-bubbles.scss +134 -68
- package/css/chips.scss +109 -19
- package/css/colors.scss +32 -32
- package/css/datepicker.scss +336 -336
- package/css/defaults.scss +90 -90
- package/css/docs.scss +529 -0
- package/css/editor.scss +36 -0
- package/css/file-uploader.scss +1 -1
- package/css/flyout-menu.scss +361 -361
- package/css/form.scss +0 -15
- package/css/gallery.scss +65 -6
- package/css/grid.scss +41 -40
- package/css/group-picker.scss +345 -0
- package/css/guitar-chords.css +250 -250
- package/css/icons.scss +330 -330
- package/css/parameters.scss +3 -3
- package/css/placeholder.scss +33 -33
- package/css/popover.scss +206 -0
- package/css/progress.scss +76 -32
- package/css/properties.scss +51 -36
- package/css/push-menu.scss +302 -174
- package/css/reset.scss +39 -39
- package/css/scrollbar.scss +62 -5
- package/css/sidebar-nav.scss +92 -0
- package/css/spinner.scss +65 -65
- package/css/stepper.scss +48 -12
- package/css/style.css +3159 -254
- package/css/style.css.map +1 -1
- package/css/style.min.css +1 -1
- package/css/style.scss +51 -45
- package/css/table.scss +199 -199
- package/css/tabs.scss +154 -123
- package/css/timeline.scss +83 -38
- package/css/timepicker.scss +100 -5
- package/css/toast.scss +81 -81
- package/css/virtual-dropdown.scss +35 -29
- package/js/calendar.js +532 -0
- package/js/calendar.ts +706 -0
- package/js/chart.js +573 -257
- package/js/chart.ts +692 -0
- package/js/code-viewer.js +10 -10
- package/js/code-viewer.ts +188 -188
- package/js/datepicker.ts +627 -627
- package/js/docs-nav.js +204 -0
- package/js/dropdown.ts +179 -179
- package/js/editor.js +50 -6
- package/js/editor.ts +483 -444
- package/js/file-uploader.js +1 -0
- package/js/file-uploader.ts +1 -0
- package/js/flyout-menu.js +14 -14
- package/js/flyout-menu.ts +249 -249
- package/js/form-builder.js +106 -106
- package/js/gallery.js +14 -8
- package/js/gallery.ts +245 -236
- package/js/group-picker.js +342 -0
- package/js/group-picker.ts +447 -0
- package/js/guitar-chords.js +268 -268
- package/js/lazy-loader.js +121 -121
- package/js/modal.ts +166 -166
- package/js/popover.js +163 -0
- package/js/popover.ts +219 -0
- package/js/position.js +108 -0
- package/js/position.ts +111 -0
- package/js/push-menu.js +113 -0
- package/js/push-menu.ts +284 -145
- package/js/request.js +50 -50
- package/js/scroll.ts +47 -47
- package/js/scrollbar.js +13 -0
- package/js/scrollbar.ts +324 -307
- package/js/select.ts +216 -216
- package/js/sidebar-nav.js +41 -0
- package/js/sidebar-nav.ts +66 -0
- package/js/table.ts +452 -452
- package/js/tabs.ts +279 -279
- package/js/theme.js +17 -6
- package/js/theme.ts +234 -224
- package/js/toast.ts +137 -137
- package/js/tooltip.js +6 -60
- package/js/tooltip.ts +184 -251
- package/js/tsconfig.json +18 -18
- package/js/utils.ts +83 -83
- package/js/virtual-dropdown.js +25 -25
- package/js/virtual-dropdown.ts +365 -365
- package/package.json +39 -39
- package/js/index.js +0 -816
- package/js/index.ts +0 -987
package/js/gallery.ts
CHANGED
|
@@ -1,236 +1,245 @@
|
|
|
1
|
-
interface ImageData {
|
|
2
|
-
src: string;
|
|
3
|
-
title: string;
|
|
4
|
-
desc: string;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
interface MasonryGalleryOptions {
|
|
8
|
-
minColumnWidth?: number;
|
|
9
|
-
scrollThreshold?: number;
|
|
10
|
-
loaderSelector?: string;
|
|
11
|
-
reload?: number;
|
|
12
|
-
fetchFunction?: () => Promise<ImageData[]>;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
class MasonryGallery {
|
|
16
|
-
private container: HTMLElement;
|
|
17
|
-
private readonly loader: HTMLElement | null;
|
|
18
|
-
private options: Required<Omit<MasonryGalleryOptions, "loaderSelector">>;
|
|
19
|
-
private columns: HTMLDivElement[] = [];
|
|
20
|
-
private isFetching: boolean = false;
|
|
21
|
-
private resizeObserver: ResizeObserver | null = null;
|
|
22
|
-
private abortController: AbortController | null = null;
|
|
23
|
-
private reloaded = 0;
|
|
24
|
-
|
|
25
|
-
constructor(containerId: string, options: MasonryGalleryOptions = {}) {
|
|
26
|
-
const container = document.getElementById(containerId);
|
|
27
|
-
if (!container) {
|
|
28
|
-
throw new Error(`Container with id "${containerId}" not found`);
|
|
29
|
-
}
|
|
30
|
-
this.container = container;
|
|
31
|
-
this.loader = document.querySelector(options.loaderSelector || ".loader");
|
|
32
|
-
|
|
33
|
-
this.options = {
|
|
34
|
-
minColumnWidth: options.minColumnWidth ?? 250,
|
|
35
|
-
scrollThreshold: options.scrollThreshold ?? 100,
|
|
36
|
-
reload: 2,
|
|
37
|
-
fetchFunction: options.fetchFunction ?? this.fetchMockImages,
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
this.init();
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
private init(): void {
|
|
44
|
-
this.setupLayout();
|
|
45
|
-
this.loadMoreImages();
|
|
46
|
-
this.addEventListeners();
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
private setupLayout(): void {
|
|
50
|
-
const containerWidth = this.container.getBoundingClientRect().width;
|
|
51
|
-
const numColumns = Math.max(
|
|
52
|
-
1,
|
|
53
|
-
Math.floor(containerWidth / this.options.minColumnWidth),
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
if (this.columns.length !== numColumns) {
|
|
57
|
-
this.container.innerHTML = "";
|
|
58
|
-
this.columns = [];
|
|
59
|
-
|
|
60
|
-
for (let i = 0; i < numColumns; i++) {
|
|
61
|
-
const col = document.createElement("div");
|
|
62
|
-
col.className = "masonry-column";
|
|
63
|
-
this.container.appendChild(col);
|
|
64
|
-
this.columns.push(col);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
private addEventListeners(): void {
|
|
70
|
-
let resizeTimeout: number;
|
|
71
|
-
window.addEventListener("resize", () => {
|
|
72
|
-
clearTimeout(resizeTimeout);
|
|
73
|
-
resizeTimeout = setTimeout(() => {
|
|
74
|
-
this.reLayout();
|
|
75
|
-
}, 200);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
this.abortController = new AbortController();
|
|
79
|
-
window.addEventListener("scroll", this.handleScroll, {
|
|
80
|
-
passive: true,
|
|
81
|
-
signal: this.abortController.signal,
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
private reLayout(): void {
|
|
86
|
-
const items: HTMLElement[] = [];
|
|
87
|
-
this.columns.forEach((col) => {
|
|
88
|
-
Array.from(col.children).forEach((child) => {
|
|
89
|
-
items.push(child as HTMLElement);
|
|
90
|
-
});
|
|
91
|
-
col.innerHTML = "";
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
const availableWidth = Math.min(1200, window.innerWidth - 40);
|
|
95
|
-
const numColumns = Math.max(
|
|
96
|
-
1,
|
|
97
|
-
Math.floor(availableWidth / this.options.minColumnWidth),
|
|
98
|
-
);
|
|
99
|
-
|
|
100
|
-
if (this.columns.length !== numColumns) {
|
|
101
|
-
this.container.innerHTML = "";
|
|
102
|
-
this.columns = [];
|
|
103
|
-
|
|
104
|
-
for (let i = 0; i < numColumns; i++) {
|
|
105
|
-
const col = document.createElement("div");
|
|
106
|
-
col.className = "masonry-column";
|
|
107
|
-
this.container.appendChild(col);
|
|
108
|
-
this.columns.push(col);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
items.forEach((item) => {
|
|
113
|
-
this.addToShortestColumn(item);
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
private handleScroll = (): void => {
|
|
118
|
-
if (this.isFetching) return;
|
|
119
|
-
|
|
120
|
-
const rect = this.container.getBoundingClientRect();
|
|
121
|
-
if (rect.bottom > 0 && rect.bottom <= window.innerHeight + this.options.scrollThreshold) {
|
|
122
|
-
this.loadMoreImages();
|
|
123
|
-
}
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
private async loadMoreImages(isAutoFill = false): Promise<void> {
|
|
127
|
-
if (!isAutoFill) this.reloaded++;
|
|
128
|
-
if (this.options.reload > 0 && this.reloaded > this.options.reload) {
|
|
129
|
-
console.warn("Maximum reload limit reached.");
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
if (this.isFetching) return;
|
|
133
|
-
|
|
134
|
-
this.isFetching = true;
|
|
135
|
-
this.toggleLoader(true);
|
|
136
|
-
|
|
137
|
-
try {
|
|
138
|
-
const newImages = await this.options.fetchFunction();
|
|
139
|
-
this.renderImages(newImages);
|
|
140
|
-
} catch (error) {
|
|
141
|
-
throw new Error("Error loading images: " + error);
|
|
142
|
-
} finally {
|
|
143
|
-
this.isFetching = false;
|
|
144
|
-
this.toggleLoader(false);
|
|
145
|
-
// If the rendered content doesn't fill the viewport, auto-load the next
|
|
146
|
-
// batch without waiting for a scroll event (multi-column layout is shorter)
|
|
147
|
-
requestAnimationFrame(() => {
|
|
148
|
-
const rect = this.container.getBoundingClientRect();
|
|
149
|
-
if (rect.bottom <= window.innerHeight + this.options.scrollThreshold) {
|
|
150
|
-
this.loadMoreImages(true);
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
private toggleLoader(show: boolean): void {
|
|
157
|
-
if (this.loader) {
|
|
158
|
-
this.loader.classList.toggle("hidden", !show);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
private fetchMockImages = (): Promise<ImageData[]> => {
|
|
163
|
-
throw Error("Method not implemented.");
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
private renderImages(imageDataList: ImageData[]): void {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
1
|
+
interface ImageData {
|
|
2
|
+
src: string;
|
|
3
|
+
title: string;
|
|
4
|
+
desc: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
interface MasonryGalleryOptions {
|
|
8
|
+
minColumnWidth?: number;
|
|
9
|
+
scrollThreshold?: number;
|
|
10
|
+
loaderSelector?: string;
|
|
11
|
+
reload?: number;
|
|
12
|
+
fetchFunction?: () => Promise<ImageData[]>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
class MasonryGallery {
|
|
16
|
+
private container: HTMLElement;
|
|
17
|
+
private readonly loader: HTMLElement | null;
|
|
18
|
+
private options: Required<Omit<MasonryGalleryOptions, "loaderSelector">>;
|
|
19
|
+
private columns: HTMLDivElement[] = [];
|
|
20
|
+
private isFetching: boolean = false;
|
|
21
|
+
private resizeObserver: ResizeObserver | null = null;
|
|
22
|
+
private abortController: AbortController | null = null;
|
|
23
|
+
private reloaded = 0;
|
|
24
|
+
|
|
25
|
+
constructor(containerId: string, options: MasonryGalleryOptions = {}) {
|
|
26
|
+
const container = document.getElementById(containerId);
|
|
27
|
+
if (!container) {
|
|
28
|
+
throw new Error(`Container with id "${containerId}" not found`);
|
|
29
|
+
}
|
|
30
|
+
this.container = container;
|
|
31
|
+
this.loader = document.querySelector(options.loaderSelector || ".loader");
|
|
32
|
+
|
|
33
|
+
this.options = {
|
|
34
|
+
minColumnWidth: options.minColumnWidth ?? 250,
|
|
35
|
+
scrollThreshold: options.scrollThreshold ?? 100,
|
|
36
|
+
reload: 2,
|
|
37
|
+
fetchFunction: options.fetchFunction ?? this.fetchMockImages,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
this.init();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private init(): void {
|
|
44
|
+
this.setupLayout();
|
|
45
|
+
this.loadMoreImages();
|
|
46
|
+
this.addEventListeners();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
private setupLayout(): void {
|
|
50
|
+
const containerWidth = this.container.getBoundingClientRect().width;
|
|
51
|
+
const numColumns = Math.max(
|
|
52
|
+
1,
|
|
53
|
+
Math.floor(containerWidth / this.options.minColumnWidth),
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
if (this.columns.length !== numColumns) {
|
|
57
|
+
this.container.innerHTML = "";
|
|
58
|
+
this.columns = [];
|
|
59
|
+
|
|
60
|
+
for (let i = 0; i < numColumns; i++) {
|
|
61
|
+
const col = document.createElement("div");
|
|
62
|
+
col.className = "masonry-column";
|
|
63
|
+
this.container.appendChild(col);
|
|
64
|
+
this.columns.push(col);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private addEventListeners(): void {
|
|
70
|
+
let resizeTimeout: number;
|
|
71
|
+
window.addEventListener("resize", () => {
|
|
72
|
+
clearTimeout(resizeTimeout);
|
|
73
|
+
resizeTimeout = setTimeout(() => {
|
|
74
|
+
this.reLayout();
|
|
75
|
+
}, 200);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
this.abortController = new AbortController();
|
|
79
|
+
window.addEventListener("scroll", this.handleScroll, {
|
|
80
|
+
passive: true,
|
|
81
|
+
signal: this.abortController.signal,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private reLayout(): void {
|
|
86
|
+
const items: HTMLElement[] = [];
|
|
87
|
+
this.columns.forEach((col) => {
|
|
88
|
+
Array.from(col.children).forEach((child) => {
|
|
89
|
+
items.push(child as HTMLElement);
|
|
90
|
+
});
|
|
91
|
+
col.innerHTML = "";
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const availableWidth = Math.min(1200, window.innerWidth - 40);
|
|
95
|
+
const numColumns = Math.max(
|
|
96
|
+
1,
|
|
97
|
+
Math.floor(availableWidth / this.options.minColumnWidth),
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
if (this.columns.length !== numColumns) {
|
|
101
|
+
this.container.innerHTML = "";
|
|
102
|
+
this.columns = [];
|
|
103
|
+
|
|
104
|
+
for (let i = 0; i < numColumns; i++) {
|
|
105
|
+
const col = document.createElement("div");
|
|
106
|
+
col.className = "masonry-column";
|
|
107
|
+
this.container.appendChild(col);
|
|
108
|
+
this.columns.push(col);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
items.forEach((item) => {
|
|
113
|
+
this.addToShortestColumn(item);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private handleScroll = (): void => {
|
|
118
|
+
if (this.isFetching) return;
|
|
119
|
+
|
|
120
|
+
const rect = this.container.getBoundingClientRect();
|
|
121
|
+
if (rect.bottom > 0 && rect.bottom <= window.innerHeight + this.options.scrollThreshold) {
|
|
122
|
+
this.loadMoreImages();
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
private async loadMoreImages(isAutoFill = false): Promise<void> {
|
|
127
|
+
if (!isAutoFill) this.reloaded++;
|
|
128
|
+
if (this.options.reload > 0 && this.reloaded > this.options.reload) {
|
|
129
|
+
console.warn("Maximum reload limit reached.");
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if (this.isFetching) return;
|
|
133
|
+
|
|
134
|
+
this.isFetching = true;
|
|
135
|
+
this.toggleLoader(true);
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
const newImages = await this.options.fetchFunction();
|
|
139
|
+
this.renderImages(newImages);
|
|
140
|
+
} catch (error) {
|
|
141
|
+
throw new Error("Error loading images: " + error);
|
|
142
|
+
} finally {
|
|
143
|
+
this.isFetching = false;
|
|
144
|
+
this.toggleLoader(false);
|
|
145
|
+
// If the rendered content doesn't fill the viewport, auto-load the next
|
|
146
|
+
// batch without waiting for a scroll event (multi-column layout is shorter)
|
|
147
|
+
requestAnimationFrame(() => {
|
|
148
|
+
const rect = this.container.getBoundingClientRect();
|
|
149
|
+
if (rect.bottom <= window.innerHeight + this.options.scrollThreshold) {
|
|
150
|
+
this.loadMoreImages(true);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
private toggleLoader(show: boolean): void {
|
|
157
|
+
if (this.loader) {
|
|
158
|
+
this.loader.classList.toggle("hidden", !show);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
private fetchMockImages = (): Promise<ImageData[]> => {
|
|
163
|
+
throw Error("Method not implemented.");
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
private renderImages(imageDataList: ImageData[]): void {
|
|
167
|
+
// Sort columns by current height so we start filling from the shortest.
|
|
168
|
+
// Then round-robin across them — this avoids the problem where unloaded
|
|
169
|
+
// images (0 height) cause offsetHeight-based distribution to pile all
|
|
170
|
+
// new items into a single column.
|
|
171
|
+
const sorted = [...this.columns].sort(
|
|
172
|
+
(a, b) => a.offsetHeight - b.offsetHeight,
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
imageDataList.forEach((data, index) => {
|
|
176
|
+
const item = this.createCard(data);
|
|
177
|
+
const col = sorted[index % sorted.length];
|
|
178
|
+
col.appendChild(item);
|
|
179
|
+
|
|
180
|
+
requestAnimationFrame(() => {
|
|
181
|
+
const img = item.querySelector("img");
|
|
182
|
+
if (img) {
|
|
183
|
+
img.addEventListener("load", () => img.classList.add("loaded"), {
|
|
184
|
+
once: true,
|
|
185
|
+
});
|
|
186
|
+
if (img.complete) {
|
|
187
|
+
img.classList.add("loaded");
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
private createCard(data: ImageData): HTMLDivElement {
|
|
195
|
+
const div = document.createElement("div");
|
|
196
|
+
div.className = "masonry-item";
|
|
197
|
+
|
|
198
|
+
div.innerHTML = `
|
|
199
|
+
<img src="${this.escapeHtml(data.src)}" alt="${this.escapeHtml(data.title)}" loading="lazy">
|
|
200
|
+
<div class="masonry-item-info">
|
|
201
|
+
<h3 class="masonry-item-title">${this.escapeHtml(data.title)}</h3>
|
|
202
|
+
<p class="masonry-item-desc">${this.escapeHtml(data.desc)}</p>
|
|
203
|
+
</div>
|
|
204
|
+
`;
|
|
205
|
+
|
|
206
|
+
return div;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
private escapeHtml(text: string): string {
|
|
210
|
+
const div = document.createElement("div");
|
|
211
|
+
div.textContent = text;
|
|
212
|
+
return div.innerHTML;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
private addToShortestColumn(element: HTMLElement): void {
|
|
216
|
+
if (this.columns.length === 0) return;
|
|
217
|
+
|
|
218
|
+
let shortestCol = this.columns[0];
|
|
219
|
+
let minHeight = shortestCol.offsetHeight;
|
|
220
|
+
|
|
221
|
+
for (let i = 1; i < this.columns.length; i++) {
|
|
222
|
+
const h = this.columns[i].offsetHeight;
|
|
223
|
+
if (h < minHeight) {
|
|
224
|
+
minHeight = h;
|
|
225
|
+
shortestCol = this.columns[i];
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
shortestCol.appendChild(element);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
public destroy(): void {
|
|
233
|
+
if (this.resizeObserver) {
|
|
234
|
+
this.resizeObserver.disconnect();
|
|
235
|
+
this.resizeObserver = null;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (this.abortController) {
|
|
239
|
+
this.abortController.abort();
|
|
240
|
+
this.abortController = null;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export { MasonryGallery, ImageData };
|