flowbite-svelte 1.24.1 → 1.25.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.
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/split-pane/Divider.svelte +2 -1
- package/dist/split-pane/SplitPane.svelte +34 -90
- package/dist/theme/themes.d.ts +1 -0
- package/dist/theme/themes.js +1 -0
- package/dist/types.d.ts +14 -0
- package/dist/utils/nonPassiveTouch.d.ts +3 -0
- package/dist/utils/nonPassiveTouch.js +8 -0
- package/dist/virtual-masonry/VirtualMasonry.svelte +185 -0
- package/dist/virtual-masonry/VirtualMasonry.svelte.d.ts +44 -0
- package/dist/virtual-masonry/index.d.ts +3 -0
- package/dist/virtual-masonry/index.js +2 -0
- package/dist/virtual-masonry/theme.d.ts +40 -0
- package/dist/virtual-masonry/theme.js +18 -0
- package/package.json +5 -1
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { divider, dividerHitArea } from "./theme";
|
|
4
4
|
import { getTheme } from "../theme/themeUtils";
|
|
5
5
|
import clsx from "clsx";
|
|
6
|
+
import { nonPassiveTouch } from "../utils/nonPassiveTouch";
|
|
6
7
|
|
|
7
8
|
let { direction, index, onMouseDown, onTouchStart, onKeyDown, isDragging, currentSize, class: className = "" }: DividerProps = $props();
|
|
8
9
|
|
|
@@ -26,7 +27,7 @@
|
|
|
26
27
|
aria-valuetext={`${roundedSize} percent`}
|
|
27
28
|
class={divider({ direction, isDragging, class: clsx(themePane, className) })}
|
|
28
29
|
onmousedown={(e) => onMouseDown(e, index)}
|
|
29
|
-
|
|
30
|
+
use:nonPassiveTouch={(e) => onTouchStart(e, index)}
|
|
30
31
|
onkeydown={(e) => onKeyDown(e, index)}
|
|
31
32
|
>
|
|
32
33
|
<div class={dividerHitArea({ direction, class: clsx(themeDividerHitArea, className) })}></div>
|
|
@@ -311,97 +311,46 @@
|
|
|
311
311
|
document.body.style.userSelect = "";
|
|
312
312
|
}
|
|
313
313
|
|
|
314
|
-
function
|
|
315
|
-
if (
|
|
316
|
-
if (index < 0 || index + 1 >= sizes.length) return;
|
|
317
|
-
|
|
318
|
-
const currentPos = currentDirection === "horizontal" ? e.clientX : e.clientY;
|
|
319
|
-
const delta = currentPos - startPos;
|
|
320
|
-
|
|
321
|
-
if (Math.abs(delta) < MIN_DELTA) return; // Ignore very small movements
|
|
322
|
-
|
|
323
|
-
const containerSize = currentDirection === "horizontal" ? container.offsetWidth : container.offsetHeight;
|
|
324
|
-
|
|
325
|
-
// Bail out if container has zero or near-zero dimensions
|
|
326
|
-
if (containerSize < 1) return;
|
|
327
|
-
|
|
328
|
-
const deltaPercent = (delta / containerSize) * 100;
|
|
329
|
-
|
|
330
|
-
// Calculate min as percentage based on current container size
|
|
331
|
-
const minPercent = (minSize / containerSize) * 100;
|
|
332
|
-
|
|
333
|
-
// Store original sizes
|
|
334
|
-
const oldSize1 = sizes[index];
|
|
335
|
-
const oldSize2 = sizes[index + 1];
|
|
336
|
-
const totalSize = oldSize1 + oldSize2;
|
|
337
|
-
|
|
338
|
-
// Calculate desired new sizes
|
|
339
|
-
let newSize1 = oldSize1 + deltaPercent;
|
|
340
|
-
let newSize2 = oldSize2 - deltaPercent;
|
|
314
|
+
function clampPaneSizes(index: number, targetSize: number, minPercent: number, total: number): boolean {
|
|
315
|
+
if (index < 0 || index + 1 >= sizes.length) return false;
|
|
341
316
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
newSize2 = totalSize - newSize1;
|
|
317
|
+
let newSize1 = Math.min(total - minPercent, Math.max(minPercent, targetSize));
|
|
318
|
+
let newSize2 = total - newSize1;
|
|
345
319
|
|
|
346
|
-
// Check if second pane violates minimum constraint after first pane clamping
|
|
347
320
|
if (newSize2 < minPercent) {
|
|
348
321
|
newSize2 = minPercent;
|
|
349
|
-
newSize1 =
|
|
322
|
+
newSize1 = total - newSize2;
|
|
350
323
|
}
|
|
351
324
|
|
|
352
|
-
|
|
353
|
-
if (Math.abs(newSize1 - oldSize1) > MIN_CHANGE_THRESHOLD) {
|
|
325
|
+
if (Math.abs(newSize1 - sizes[index]) > MIN_CHANGE_THRESHOLD) {
|
|
354
326
|
sizes[index] = newSize1;
|
|
355
327
|
sizes[index + 1] = newSize2;
|
|
356
|
-
|
|
328
|
+
return true;
|
|
357
329
|
}
|
|
330
|
+
|
|
331
|
+
return false;
|
|
358
332
|
}
|
|
359
333
|
|
|
360
|
-
function
|
|
334
|
+
function applyResize(currentPos: number, index: number) {
|
|
361
335
|
if (!isDragging || !container) return;
|
|
362
336
|
if (index < 0 || index + 1 >= sizes.length) return;
|
|
363
337
|
|
|
364
|
-
e.preventDefault(); // Prevent scrolling while dragging
|
|
365
|
-
|
|
366
|
-
const touch = e.touches[0];
|
|
367
|
-
const currentPos = currentDirection === "horizontal" ? touch.clientX : touch.clientY;
|
|
368
338
|
const delta = currentPos - startPos;
|
|
339
|
+
if (Math.abs(delta) < MIN_DELTA) return;
|
|
369
340
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
const containerSize = currentDirection === "horizontal" ? container.offsetWidth : container.offsetHeight;
|
|
373
|
-
|
|
374
|
-
// Bail out if container has zero or near-zero dimensions
|
|
375
|
-
if (containerSize < 1) return;
|
|
376
|
-
|
|
377
|
-
const deltaPercent = (delta / containerSize) * 100;
|
|
341
|
+
const currentContainerSize = currentDirection === "horizontal" ? container.offsetWidth : container.offsetHeight;
|
|
342
|
+
if (currentContainerSize < 1) return;
|
|
378
343
|
|
|
379
|
-
|
|
380
|
-
const minPercent = (minSize /
|
|
344
|
+
const deltaPercent = (delta / currentContainerSize) * 100;
|
|
345
|
+
const minPercent = (minSize / currentContainerSize) * 100;
|
|
381
346
|
|
|
382
|
-
// Store original sizes
|
|
383
347
|
const oldSize1 = sizes[index];
|
|
384
348
|
const oldSize2 = sizes[index + 1];
|
|
385
349
|
const totalSize = oldSize1 + oldSize2;
|
|
386
350
|
|
|
387
|
-
|
|
388
|
-
let newSize1 = oldSize1 + deltaPercent;
|
|
389
|
-
let newSize2 = oldSize2 - deltaPercent;
|
|
390
|
-
|
|
391
|
-
// Apply minimum constraints - clamp to valid range
|
|
392
|
-
newSize1 = Math.max(minPercent, newSize1);
|
|
393
|
-
newSize2 = totalSize - newSize1;
|
|
394
|
-
|
|
395
|
-
// Check if second pane violates minimum constraint after first pane clamping
|
|
396
|
-
if (newSize2 < minPercent) {
|
|
397
|
-
newSize2 = minPercent;
|
|
398
|
-
newSize1 = totalSize - newSize2;
|
|
399
|
-
}
|
|
351
|
+
const targetSize = oldSize1 + deltaPercent;
|
|
400
352
|
|
|
401
|
-
|
|
402
|
-
if (Math.abs(newSize1 - oldSize1) > MIN_CHANGE_THRESHOLD) {
|
|
403
|
-
sizes[index] = newSize1;
|
|
404
|
-
sizes[index + 1] = newSize2;
|
|
353
|
+
if (clampPaneSizes(index, targetSize, minPercent, totalSize)) {
|
|
405
354
|
startPos = currentPos;
|
|
406
355
|
}
|
|
407
356
|
}
|
|
@@ -410,41 +359,24 @@
|
|
|
410
359
|
if (!container) return;
|
|
411
360
|
if (index < 0 || index + 1 >= sizes.length) return;
|
|
412
361
|
|
|
413
|
-
const step = keyboardStep;
|
|
414
|
-
let handled = false;
|
|
415
|
-
|
|
416
362
|
const isHorizontal = currentDirection === "horizontal";
|
|
417
363
|
const increaseKeys = isHorizontal ? ["ArrowRight"] : ["ArrowDown"];
|
|
418
364
|
const decreaseKeys = isHorizontal ? ["ArrowLeft"] : ["ArrowUp"];
|
|
419
365
|
|
|
420
366
|
const containerSize = isHorizontal ? container.offsetWidth : container.offsetHeight;
|
|
421
|
-
// Bail out if container has zero or near-zero dimensions
|
|
422
367
|
if (containerSize < 1) return;
|
|
423
368
|
|
|
424
369
|
const minPercent = (minSize / containerSize) * 100;
|
|
425
|
-
|
|
426
370
|
const total = sizes[index] + sizes[index + 1];
|
|
427
371
|
|
|
428
|
-
|
|
429
|
-
let newSize1 = Math.min(total - minPercent, Math.max(minPercent, target));
|
|
430
|
-
let newSize2 = total - newSize1;
|
|
431
|
-
|
|
432
|
-
if (newSize2 < minPercent) {
|
|
433
|
-
newSize2 = minPercent;
|
|
434
|
-
newSize1 = total - newSize2;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
if (Math.abs(newSize1 - sizes[index]) > MIN_CHANGE_THRESHOLD) {
|
|
438
|
-
sizes[index] = newSize1;
|
|
439
|
-
sizes[index + 1] = newSize2;
|
|
440
|
-
handled = true;
|
|
441
|
-
}
|
|
442
|
-
};
|
|
372
|
+
let handled = false;
|
|
443
373
|
|
|
444
374
|
if (increaseKeys.includes(e.key)) {
|
|
445
|
-
|
|
375
|
+
const targetSize = sizes[index] + keyboardStep;
|
|
376
|
+
handled = clampPaneSizes(index, targetSize, minPercent, total);
|
|
446
377
|
} else if (decreaseKeys.includes(e.key)) {
|
|
447
|
-
|
|
378
|
+
const targetSize = sizes[index] - keyboardStep;
|
|
379
|
+
handled = clampPaneSizes(index, targetSize, minPercent, total);
|
|
448
380
|
} else if (e.key === "Enter" || e.key === " ") {
|
|
449
381
|
// Reset to equal sizes
|
|
450
382
|
const equal = 100 / registeredPanes;
|
|
@@ -456,6 +388,18 @@
|
|
|
456
388
|
e.preventDefault();
|
|
457
389
|
}
|
|
458
390
|
}
|
|
391
|
+
|
|
392
|
+
function resize(e: MouseEvent, index: number) {
|
|
393
|
+
const currentPos = currentDirection === "horizontal" ? e.clientX : e.clientY;
|
|
394
|
+
applyResize(currentPos, index);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
function resizeTouch(e: TouchEvent, index: number) {
|
|
398
|
+
e.preventDefault(); // Prevent scrolling while dragging
|
|
399
|
+
const touch = e.touches[0];
|
|
400
|
+
const currentPos = currentDirection === "horizontal" ? touch.clientX : touch.clientY;
|
|
401
|
+
applyResize(currentPos, index);
|
|
402
|
+
}
|
|
459
403
|
</script>
|
|
460
404
|
|
|
461
405
|
<div bind:this={container} class={splitpane({ direction: currentDirection, class: clsx(theme, className) })}>
|
package/dist/theme/themes.d.ts
CHANGED
|
@@ -74,3 +74,4 @@ export { kanbanBoard, kanbanCard } from "../kanban/theme";
|
|
|
74
74
|
export { splitpane, pane, divider, dividerHitArea } from "../split-pane/theme";
|
|
75
75
|
export { tour } from "../tour/theme";
|
|
76
76
|
export { scrollspy } from "../scroll-spy/theme";
|
|
77
|
+
export { virtualMasonry } from "../virtual-masonry/theme";
|
package/dist/theme/themes.js
CHANGED
|
@@ -81,3 +81,4 @@ export { kanbanBoard, kanbanCard } from "../kanban/theme";
|
|
|
81
81
|
export { splitpane, pane, divider, dividerHitArea } from "../split-pane/theme";
|
|
82
82
|
export { tour } from "../tour/theme";
|
|
83
83
|
export { scrollspy } from "../scroll-spy/theme";
|
|
84
|
+
export { virtualMasonry } from "../virtual-masonry/theme";
|
package/dist/types.d.ts
CHANGED
|
@@ -1883,3 +1883,17 @@ export interface ScrollSpyProps extends ScrollSpyVariants, HTMLAttributes<HTMLEl
|
|
|
1883
1883
|
/** Callback when navigation item is clicked */
|
|
1884
1884
|
onNavigate?: (itemId: string) => void;
|
|
1885
1885
|
}
|
|
1886
|
+
import type { VirtualMasonryVariants } from "./virtual-masonry/theme";
|
|
1887
|
+
export interface VirtualMasonryProps<T = unknown> extends VirtualMasonryVariants, Omit<HTMLAttributes<HTMLDivElement>, "children"> {
|
|
1888
|
+
children: Snippet<[item: T, index: number]>;
|
|
1889
|
+
items?: T[];
|
|
1890
|
+
columns?: number;
|
|
1891
|
+
gap?: number;
|
|
1892
|
+
height?: number;
|
|
1893
|
+
overscan?: number;
|
|
1894
|
+
getItemHeight?: (item: T, index: number) => number;
|
|
1895
|
+
scrollToIndex?: (fn: (index: number) => void) => void;
|
|
1896
|
+
contained?: boolean;
|
|
1897
|
+
ariaLabel?: string;
|
|
1898
|
+
class?: ClassValue | null;
|
|
1899
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
<script lang="ts" generics="T">
|
|
2
|
+
import type { VirtualMasonryProps } from "../types";
|
|
3
|
+
import { virtualMasonry } from "./theme";
|
|
4
|
+
import clsx from "clsx";
|
|
5
|
+
import { getTheme } from "../theme/themeUtils";
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
items = [],
|
|
9
|
+
columns = 3,
|
|
10
|
+
gap = 16,
|
|
11
|
+
height = 600,
|
|
12
|
+
overscan = 200,
|
|
13
|
+
getItemHeight,
|
|
14
|
+
scrollToIndex,
|
|
15
|
+
children,
|
|
16
|
+
ariaLabel = "Virtual masonry grid",
|
|
17
|
+
class: className,
|
|
18
|
+
classes,
|
|
19
|
+
contained = false
|
|
20
|
+
}: VirtualMasonryProps<T> = $props();
|
|
21
|
+
|
|
22
|
+
const theme = getTheme("virtualMasonry");
|
|
23
|
+
|
|
24
|
+
let container: HTMLDivElement | undefined;
|
|
25
|
+
let containerWidth = $state(0);
|
|
26
|
+
let scrollTop = $state(0);
|
|
27
|
+
let rafId: number | undefined;
|
|
28
|
+
|
|
29
|
+
const styles = virtualMasonry({ contained });
|
|
30
|
+
|
|
31
|
+
const containStyle = $derived.by(() => {
|
|
32
|
+
if (!contained) return "";
|
|
33
|
+
const itemClasses = clsx(classes?.item);
|
|
34
|
+
const hasCustomContain = /\[contain:[^\]]+\]/.test(itemClasses);
|
|
35
|
+
return hasCustomContain ? "" : "contain: layout style paint;";
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Calculate column width based on container width
|
|
39
|
+
const columnWidth = $derived.by(() => {
|
|
40
|
+
if (containerWidth === 0) return 0;
|
|
41
|
+
return (containerWidth - gap * (columns - 1)) / columns;
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Position items in columns
|
|
45
|
+
interface PositionedItem {
|
|
46
|
+
item: T;
|
|
47
|
+
index: number;
|
|
48
|
+
x: number;
|
|
49
|
+
y: number;
|
|
50
|
+
height: number;
|
|
51
|
+
column: number;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const positionedItems = $derived.by((): PositionedItem[] => {
|
|
55
|
+
if (columnWidth === 0) return [];
|
|
56
|
+
|
|
57
|
+
const columnHeights = new Array(columns).fill(0);
|
|
58
|
+
const positioned: PositionedItem[] = [];
|
|
59
|
+
|
|
60
|
+
for (let i = 0; i < items.length; i++) {
|
|
61
|
+
// Find shortest column
|
|
62
|
+
const shortestColumn = columnHeights.indexOf(Math.min(...columnHeights));
|
|
63
|
+
const itemHeight = getItemHeight ? getItemHeight(items[i], i) : 200;
|
|
64
|
+
|
|
65
|
+
positioned.push({
|
|
66
|
+
item: items[i],
|
|
67
|
+
index: i,
|
|
68
|
+
x: shortestColumn * (columnWidth + gap),
|
|
69
|
+
y: columnHeights[shortestColumn],
|
|
70
|
+
height: itemHeight,
|
|
71
|
+
column: shortestColumn
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
columnHeights[shortestColumn] += itemHeight + gap;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return positioned;
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Total height is the tallest column
|
|
81
|
+
const totalHeight = $derived.by(() => {
|
|
82
|
+
if (positionedItems.length === 0) return 0;
|
|
83
|
+
return Math.max(...positionedItems.map((item) => item.y + item.height));
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// Visible items based on scroll position with overscan
|
|
87
|
+
const visibleItems = $derived.by(() => {
|
|
88
|
+
const viewportTop = scrollTop - overscan;
|
|
89
|
+
const viewportBottom = scrollTop + height + overscan;
|
|
90
|
+
|
|
91
|
+
return positionedItems.filter((item) => {
|
|
92
|
+
const itemTop = item.y;
|
|
93
|
+
const itemBottom = item.y + item.height;
|
|
94
|
+
return itemBottom >= viewportTop && itemTop <= viewportBottom;
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Performance optimized scroll handler using RAF
|
|
99
|
+
function handleScroll() {
|
|
100
|
+
if (rafId) cancelAnimationFrame(rafId);
|
|
101
|
+
rafId = requestAnimationFrame(() => {
|
|
102
|
+
if (container) scrollTop = container.scrollTop;
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Scroll to specific index
|
|
107
|
+
function scrollToIndexImpl(index: number) {
|
|
108
|
+
if (!container || index < 0 || index >= items.length) return;
|
|
109
|
+
const item = positionedItems[index];
|
|
110
|
+
if (item) {
|
|
111
|
+
container.scrollTop = item.y;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Bind scrollToIndex function to parent component
|
|
116
|
+
$effect(() => {
|
|
117
|
+
if (scrollToIndex) {
|
|
118
|
+
scrollToIndex(scrollToIndexImpl);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// Measure container width on mount and resize
|
|
123
|
+
$effect(() => {
|
|
124
|
+
if (!container) return;
|
|
125
|
+
|
|
126
|
+
const resizeObserver = new ResizeObserver((entries) => {
|
|
127
|
+
for (const entry of entries) {
|
|
128
|
+
containerWidth = entry.contentRect.width;
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
resizeObserver.observe(container);
|
|
133
|
+
|
|
134
|
+
return () => {
|
|
135
|
+
resizeObserver.disconnect();
|
|
136
|
+
if (rafId) cancelAnimationFrame(rafId);
|
|
137
|
+
};
|
|
138
|
+
});
|
|
139
|
+
</script>
|
|
140
|
+
|
|
141
|
+
<div
|
|
142
|
+
bind:this={container}
|
|
143
|
+
onscroll={handleScroll}
|
|
144
|
+
role="list"
|
|
145
|
+
aria-label={ariaLabel}
|
|
146
|
+
class={styles.container({ class: clsx(theme?.container, className) })}
|
|
147
|
+
style={`height:${height}px; position:relative;`}
|
|
148
|
+
>
|
|
149
|
+
<div class={styles.spacer({ class: clsx(theme?.spacer, classes?.spacer) })} style={`height:${totalHeight}px;`}>
|
|
150
|
+
<div class={styles.content({ class: clsx(theme?.content, classes?.content) })}>
|
|
151
|
+
{#each visibleItems as { item, index, x, y, height: itemHeight } (index)}
|
|
152
|
+
<div
|
|
153
|
+
role="listitem"
|
|
154
|
+
aria-setsize={items.length}
|
|
155
|
+
aria-posinset={index + 1}
|
|
156
|
+
class={styles.item({ class: clsx(theme?.item, classes?.item) })}
|
|
157
|
+
style={`position:absolute; left:${x}px; top:${y}px; width:${columnWidth}px; height:${itemHeight}px; ${containStyle}`}
|
|
158
|
+
>
|
|
159
|
+
{@render children?.(item, index)}
|
|
160
|
+
</div>
|
|
161
|
+
{/each}
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
<!--
|
|
167
|
+
@component
|
|
168
|
+
VirtualMasonry - Virtualized masonry/pinterest layout for efficient rendering of large image grids
|
|
169
|
+
[Go to docs](https://flowbite-svelte.com/)
|
|
170
|
+
## Type
|
|
171
|
+
[VirtualMasonryProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts)
|
|
172
|
+
## Props
|
|
173
|
+
@prop items = []
|
|
174
|
+
@prop columns = 3
|
|
175
|
+
@prop gap = 16
|
|
176
|
+
@prop height = 600
|
|
177
|
+
@prop overscan = 200
|
|
178
|
+
@prop getItemHeight
|
|
179
|
+
@prop scrollToIndex
|
|
180
|
+
@prop children
|
|
181
|
+
@prop ariaLabel = "Virtual masonry grid"
|
|
182
|
+
@prop contained = false
|
|
183
|
+
@prop class: className
|
|
184
|
+
@prop classes
|
|
185
|
+
-->
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { VirtualMasonryProps } from "../types";
|
|
2
|
+
declare function $$render<T>(): {
|
|
3
|
+
props: VirtualMasonryProps<T>;
|
|
4
|
+
exports: {};
|
|
5
|
+
bindings: "";
|
|
6
|
+
slots: {};
|
|
7
|
+
events: {};
|
|
8
|
+
};
|
|
9
|
+
declare class __sveltets_Render<T> {
|
|
10
|
+
props(): ReturnType<typeof $$render<T>>['props'];
|
|
11
|
+
events(): ReturnType<typeof $$render<T>>['events'];
|
|
12
|
+
slots(): ReturnType<typeof $$render<T>>['slots'];
|
|
13
|
+
bindings(): "";
|
|
14
|
+
exports(): {};
|
|
15
|
+
}
|
|
16
|
+
interface $$IsomorphicComponent {
|
|
17
|
+
new <T>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
|
|
18
|
+
$$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
|
|
19
|
+
} & ReturnType<__sveltets_Render<T>['exports']>;
|
|
20
|
+
<T>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
|
|
21
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* VirtualMasonry - Virtualized masonry/pinterest layout for efficient rendering of large image grids
|
|
25
|
+
* [Go to docs](https://flowbite-svelte.com/)
|
|
26
|
+
* ## Type
|
|
27
|
+
* [VirtualMasonryProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts)
|
|
28
|
+
* ## Props
|
|
29
|
+
* @prop items = []
|
|
30
|
+
* @prop columns = 3
|
|
31
|
+
* @prop gap = 16
|
|
32
|
+
* @prop height = 600
|
|
33
|
+
* @prop overscan = 200
|
|
34
|
+
* @prop getItemHeight
|
|
35
|
+
* @prop scrollToIndex
|
|
36
|
+
* @prop children
|
|
37
|
+
* @prop ariaLabel = "Virtual masonry grid"
|
|
38
|
+
* @prop contained = false
|
|
39
|
+
* @prop class: className
|
|
40
|
+
* @prop classes
|
|
41
|
+
*/
|
|
42
|
+
declare const VirtualMasonry: $$IsomorphicComponent;
|
|
43
|
+
type VirtualMasonry<T> = InstanceType<typeof VirtualMasonry<T>>;
|
|
44
|
+
export default VirtualMasonry;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type VariantProps } from "tailwind-variants";
|
|
2
|
+
import type { Classes } from "../theme/themeUtils";
|
|
3
|
+
export declare const virtualMasonry: import("tailwind-variants").TVReturnType<{
|
|
4
|
+
contained: {
|
|
5
|
+
true: {
|
|
6
|
+
item: string;
|
|
7
|
+
};
|
|
8
|
+
false: {};
|
|
9
|
+
};
|
|
10
|
+
}, {
|
|
11
|
+
container: string;
|
|
12
|
+
spacer: string;
|
|
13
|
+
content: string;
|
|
14
|
+
item: string;
|
|
15
|
+
}, undefined, {
|
|
16
|
+
contained: {
|
|
17
|
+
true: {
|
|
18
|
+
item: string;
|
|
19
|
+
};
|
|
20
|
+
false: {};
|
|
21
|
+
};
|
|
22
|
+
}, {
|
|
23
|
+
container: string;
|
|
24
|
+
spacer: string;
|
|
25
|
+
content: string;
|
|
26
|
+
item: string;
|
|
27
|
+
}, import("tailwind-variants").TVReturnType<{
|
|
28
|
+
contained: {
|
|
29
|
+
true: {
|
|
30
|
+
item: string;
|
|
31
|
+
};
|
|
32
|
+
false: {};
|
|
33
|
+
};
|
|
34
|
+
}, {
|
|
35
|
+
container: string;
|
|
36
|
+
spacer: string;
|
|
37
|
+
content: string;
|
|
38
|
+
item: string;
|
|
39
|
+
}, undefined, unknown, unknown, undefined>>;
|
|
40
|
+
export type VirtualMasonryVariants = VariantProps<typeof virtualMasonry> & Classes<typeof virtualMasonry>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { tv } from "tailwind-variants";
|
|
2
|
+
export const virtualMasonry = tv({
|
|
3
|
+
slots: {
|
|
4
|
+
container: "overflow-y-auto scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-transparent",
|
|
5
|
+
spacer: "relative",
|
|
6
|
+
content: "relative w-full",
|
|
7
|
+
item: ""
|
|
8
|
+
},
|
|
9
|
+
variants: {
|
|
10
|
+
contained: {
|
|
11
|
+
true: { item: "[contain:layout_style_paint]" },
|
|
12
|
+
false: {}
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
defaultVariants: {
|
|
16
|
+
contained: false
|
|
17
|
+
}
|
|
18
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flowbite-svelte",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.25.0",
|
|
4
4
|
"description": "Flowbite components for Svelte",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"author": {
|
|
@@ -861,6 +861,10 @@
|
|
|
861
861
|
"types": "./dist/video/Video.svelte.d.ts",
|
|
862
862
|
"svelte": "./dist/video/Video.svelte"
|
|
863
863
|
},
|
|
864
|
+
"./VirtualMasonry.svelte": {
|
|
865
|
+
"types": "./dist/virtual-masonry/VirtualMasonry.svelte.d.ts",
|
|
866
|
+
"svelte": "./dist/virtual-masonry/VirtualMasonry.svelte"
|
|
867
|
+
},
|
|
864
868
|
"./VirtualList.svelte": {
|
|
865
869
|
"types": "./dist/virtuallist/VirtualList.svelte.d.ts",
|
|
866
870
|
"svelte": "./dist/virtuallist/VirtualList.svelte"
|