flowbite-svelte 1.18.2 → 1.19.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/dist/alert/Alert.svelte +1 -1
- package/dist/badge/Badge.svelte +1 -1
- package/dist/carousel/Carousel.svelte +2 -2
- package/dist/dialog/Dialog.svelte +5 -5
- package/dist/forms/input-field/Input.svelte +5 -5
- package/dist/forms/phoneinput/PhoneInput.svelte.d.ts +1 -1
- package/dist/forms/tags/Tags.svelte +6 -10
- package/dist/forms/timepicker/Timepicker.svelte +0 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/mega-menu/MegaMenu.svelte +1 -8
- package/dist/navbar/NavHamburger.svelte +1 -1
- package/dist/rating/Review.svelte +1 -2
- package/dist/rating/Review.svelte.d.ts +0 -1
- package/dist/step-indicator/StepIndicator.svelte +1 -1
- package/dist/stepper/DetailedStepper.svelte +1 -1
- package/dist/stepper/VerticalStepper.svelte +1 -1
- package/dist/theme/themes.d.ts +1 -0
- package/dist/theme/themes.js +3 -0
- package/dist/toast/Toast.svelte +1 -1
- package/dist/tooltip/Tooltip.svelte +0 -3
- package/dist/types.d.ts +12 -1
- package/dist/virtuallist/VirtualList.svelte +118 -0
- package/dist/virtuallist/VirtualList.svelte.d.ts +19 -0
- package/dist/virtuallist/index.d.ts +2 -0
- package/dist/virtuallist/index.js +2 -0
- package/dist/virtuallist/theme.d.ts +40 -0
- package/dist/virtuallist/theme.js +8 -0
- package/package.json +5 -1
package/dist/alert/Alert.svelte
CHANGED
package/dist/badge/Badge.svelte
CHANGED
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
const nextSlide = () => changeSlide(_state.index + 1);
|
|
58
58
|
const prevSlide = () => changeSlide(_state.index - 1);
|
|
59
59
|
|
|
60
|
-
const loop = (
|
|
60
|
+
const loop = () => {
|
|
61
61
|
// loop timer
|
|
62
62
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
63
63
|
let intervalId: any;
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
let onDragStop = $derived(
|
|
128
128
|
activeDragGesture === undefined
|
|
129
129
|
? undefined
|
|
130
|
-
: (
|
|
130
|
+
: () => {
|
|
131
131
|
// These might be exposed one day, keep them safely tucked away as constants.
|
|
132
132
|
const SWIPE_MAX_DURATION = 250;
|
|
133
133
|
const SWIPE_MIN_DISTANCE = 30;
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
let { base, form: formCls, close: closeCls } = dialog();
|
|
16
16
|
|
|
17
|
-
const close = (
|
|
17
|
+
const close = () => (open = false);
|
|
18
18
|
|
|
19
19
|
// Prefer requestClose when available to trigger a cancellable "cancel" event; otherwise synthesize it.
|
|
20
20
|
const cancel = (dlg: HTMLDialogElement) => {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
if (ev.defaultPrevented) return;
|
|
35
35
|
|
|
36
36
|
ev.preventDefault(); // prevent anyway, we need clean close
|
|
37
|
-
if (!permanent) close(
|
|
37
|
+
if (!permanent) close();
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
function _onclick(ev: MouseEvent & { currentTarget: HTMLDialogElement }) {
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
if (autoclose && ev.target instanceof HTMLButtonElement && !permanent) {
|
|
53
|
-
return close(
|
|
53
|
+
return close();
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
if (result === false) return;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
close(
|
|
85
|
+
close();
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
function _ontoggle(ev: ToggleEvent & { currentTarget: HTMLDialogElement }) {
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
|
|
113
113
|
let ref: HTMLDialogElement | undefined = $state(undefined);
|
|
114
114
|
|
|
115
|
-
function close_handler(
|
|
115
|
+
function close_handler() {
|
|
116
116
|
if (form) {
|
|
117
117
|
// dialog/form mechanism will close the dialog
|
|
118
118
|
return;
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
}
|
|
104
104
|
});
|
|
105
105
|
|
|
106
|
-
function defaultHandleInput(
|
|
106
|
+
function defaultHandleInput(_event: Event) {
|
|
107
107
|
// Ensure value is treated as a string to safely check its length
|
|
108
108
|
const currentValueAsString = String(value || "");
|
|
109
109
|
if (currentValueAsString.length > 0) {
|
|
@@ -112,12 +112,12 @@
|
|
|
112
112
|
updateSuggestions();
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
function defaultHandleFocus(
|
|
115
|
+
function defaultHandleFocus() {
|
|
116
116
|
isFocused = true;
|
|
117
117
|
updateSuggestions();
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
function defaultHandleBlur(
|
|
120
|
+
function defaultHandleBlur() {
|
|
121
121
|
// Small delay to allow click on suggestion to fire first
|
|
122
122
|
setTimeout(() => {
|
|
123
123
|
isFocused = false;
|
|
@@ -174,14 +174,14 @@
|
|
|
174
174
|
if (resolvedOnFocus) {
|
|
175
175
|
resolvedOnFocus(event);
|
|
176
176
|
}
|
|
177
|
-
defaultHandleFocus(
|
|
177
|
+
defaultHandleFocus();
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
function handleBlur(event: FocusEvent) {
|
|
181
181
|
if (resolvedOnBlur) {
|
|
182
182
|
resolvedOnBlur(event);
|
|
183
183
|
}
|
|
184
|
-
defaultHandleBlur(
|
|
184
|
+
defaultHandleBlur();
|
|
185
185
|
}
|
|
186
186
|
|
|
187
187
|
function handleKeydown(event: KeyboardEvent) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { PhoneInputProps } from "../..";
|
|
2
|
-
declare const PhoneInput: import("svelte").Component<PhoneInputProps
|
|
2
|
+
declare const PhoneInput: import("svelte").Component<PhoneInputProps, {}, "">;
|
|
3
3
|
type PhoneInput = ReturnType<typeof PhoneInput>;
|
|
4
4
|
export default PhoneInput;
|
|
@@ -51,10 +51,6 @@
|
|
|
51
51
|
});
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
const checkDropdownPosition = () => {
|
|
55
|
-
if (!inputContainer) return;
|
|
56
|
-
};
|
|
57
|
-
|
|
58
54
|
const handleKeys = (event: KeyboardEvent) => {
|
|
59
55
|
if (event.key === "Enter") {
|
|
60
56
|
event.preventDefault();
|
|
@@ -102,10 +98,6 @@
|
|
|
102
98
|
}
|
|
103
99
|
};
|
|
104
100
|
|
|
105
|
-
const handleInput = () => {
|
|
106
|
-
checkDropdownPosition();
|
|
107
|
-
};
|
|
108
|
-
|
|
109
101
|
const deleteField = (index: number) => {
|
|
110
102
|
value = value.filter((_, i) => i !== index);
|
|
111
103
|
errorMessage = "";
|
|
@@ -135,7 +127,7 @@
|
|
|
135
127
|
});
|
|
136
128
|
</script>
|
|
137
129
|
|
|
138
|
-
<svelte:window
|
|
130
|
+
<svelte:window />
|
|
139
131
|
|
|
140
132
|
{#if showAvailableTags && availableTags.length > 0}
|
|
141
133
|
<P class={clsx(info(), classes?.info)}>Available tags: {availableTags.join(", ")}</P>
|
|
@@ -149,6 +141,10 @@
|
|
|
149
141
|
{/if}
|
|
150
142
|
{/if}
|
|
151
143
|
|
|
144
|
+
{#if errorMessage}
|
|
145
|
+
<P class={clsx(error(), classes?.error)}>{errorMessage}</P>
|
|
146
|
+
{/if}
|
|
147
|
+
|
|
152
148
|
<div
|
|
153
149
|
{...restProps}
|
|
154
150
|
class={base({
|
|
@@ -164,7 +160,7 @@
|
|
|
164
160
|
</div>
|
|
165
161
|
{/each}
|
|
166
162
|
<div class="relative w-full" bind:this={inputContainer}>
|
|
167
|
-
<input {...inputProps} {disabled} bind:this={inputElement} onkeydown={handleKeys}
|
|
163
|
+
<input {...inputProps} {disabled} bind:this={inputElement} onkeydown={handleKeys} bind:value={contents} placeholder={value.length === 0 ? placeholder : ""} type="text" autocomplete="off" class={inputCls({ class: clsx(styling.input) })} />
|
|
168
164
|
{#if availableTags.length > 0 && contents.trim() !== ""}
|
|
169
165
|
{@const filteredSuggestions = availableTags.filter((tag) => tag.toLowerCase().includes(contents.trim().toLowerCase()) && (!unique || !value.some((t) => t.toLowerCase() === tag.toLowerCase())))}
|
|
170
166
|
{#if filteredSuggestions.length > 0}
|
|
@@ -22,7 +22,6 @@
|
|
|
22
22
|
|
|
23
23
|
// State
|
|
24
24
|
let selectedOption = $state("");
|
|
25
|
-
let dropdownOpen = $state(false);
|
|
26
25
|
let showTimerange = $state(false);
|
|
27
26
|
|
|
28
27
|
// Helper functions using date-fns
|
|
@@ -117,7 +116,6 @@
|
|
|
117
116
|
}
|
|
118
117
|
|
|
119
118
|
function handleDropdownSelect(option: TimePickerOption): void {
|
|
120
|
-
dropdownOpen = false;
|
|
121
119
|
selectedOption = option.value;
|
|
122
120
|
notifyChange();
|
|
123
121
|
}
|
|
@@ -133,7 +131,6 @@
|
|
|
133
131
|
}
|
|
134
132
|
|
|
135
133
|
function applyTimerange(): void {
|
|
136
|
-
dropdownOpen = false;
|
|
137
134
|
notifyChange();
|
|
138
135
|
}
|
|
139
136
|
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { megamenu } from "./theme";
|
|
3
3
|
import clsx from "clsx";
|
|
4
|
-
import type { MegaMenuProps
|
|
4
|
+
import type { MegaMenuProps } from "..";
|
|
5
5
|
import Popper from "../utils/Popper.svelte";
|
|
6
6
|
import { getTheme, warnThemeDeprecation } from "../theme/themeUtils";
|
|
7
7
|
|
|
@@ -10,14 +10,7 @@
|
|
|
10
10
|
// ulClass, extraClass
|
|
11
11
|
warnThemeDeprecation("MegaMenu", { ulClass, extraClass }, { ulClass: "ul", extraClass: "extra" });
|
|
12
12
|
const styling = $derived(classes ?? { ul: ulClass, extra: extraClass });
|
|
13
|
-
|
|
14
13
|
const theme = getTheme("megamenu");
|
|
15
|
-
|
|
16
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
17
|
-
interface LinkTypeLike extends LinkType {
|
|
18
|
-
[propName: string]: any;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
14
|
const { base, div, ul, extra: extraCls } = $derived(megamenu({ full, hasExtra: !!extra }));
|
|
22
15
|
</script>
|
|
23
16
|
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
const navBreakpoint = getContext<NavbarBreakpoint>("breakpoint");
|
|
19
19
|
const { base, menu } = navbarHamburger({ breakpoint: navBreakpoint });
|
|
20
20
|
|
|
21
|
-
const toggle: MouseEventHandler<HTMLButtonElement> = (
|
|
21
|
+
const toggle: MouseEventHandler<HTMLButtonElement> = () => {
|
|
22
22
|
navState.hidden = !navState.hidden;
|
|
23
23
|
};
|
|
24
24
|
</script>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import type { ReviewProps } from "../types";
|
|
5
5
|
import { getTheme, warnThemeDeprecation } from "../theme/themeUtils";
|
|
6
6
|
|
|
7
|
-
let { children, address, item1, item2, item3, review,
|
|
7
|
+
let { children, address, item1, item2, item3, review, classes, articleClass, divClass, div2Class, div3Class, imgClass, ulClass, liClass }: ReviewProps = $props();
|
|
8
8
|
|
|
9
9
|
warnThemeDeprecation("Review", { articleClass, divClass, div2Class, div3Class, imgClass, ulClass, liClass }, { articleClass: "article", divClass: "div", div2Class: "div2", div3Class: "div3", imgClass: "img", ulClass: "ul", liClass: "li" });
|
|
10
10
|
const styling = $derived(
|
|
@@ -102,7 +102,6 @@
|
|
|
102
102
|
@prop item2
|
|
103
103
|
@prop item3
|
|
104
104
|
@prop review
|
|
105
|
-
@prop class: className
|
|
106
105
|
@prop classes
|
|
107
106
|
@prop articleClass
|
|
108
107
|
@prop divClass
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
{/if}
|
|
34
34
|
|
|
35
35
|
<div class={container({ class: clsx((theme as StepIndicatorTheme)?.container, classes?.container) })}>
|
|
36
|
-
{#each steps as
|
|
36
|
+
{#each steps as _step, i}
|
|
37
37
|
{#if i === currentStep - 1}
|
|
38
38
|
<div class={wrapper({ class: clsx((theme as StepIndicatorTheme)?.wrapper, classes?.wrapper) })}>
|
|
39
39
|
<div class={stepCls({ class: clsx(getStepStateClasses(i, currentStep), getCustomStepClass(i), (theme as StepIndicatorTheme)?.step, classes?.step) })} data-state="current"></div>
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
{#if children}
|
|
19
19
|
{@render children()}
|
|
20
20
|
{:else if steps}
|
|
21
|
-
{#each steps as step
|
|
21
|
+
{#each steps as step}
|
|
22
22
|
<li class={item({ status: step.status, class: clsx(theme?.item, classes?.item) })}>
|
|
23
23
|
<span class={indicator({ status: step.status, class: clsx(theme?.indicator, classes?.indicator) })}>
|
|
24
24
|
{#if step.status === "completed" && step.icon}
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
{#if children}
|
|
19
19
|
{@render children()}
|
|
20
20
|
{:else if steps}
|
|
21
|
-
{#each steps as step
|
|
21
|
+
{#each steps as step}
|
|
22
22
|
<li class={clsx(liClass)}>
|
|
23
23
|
<div class={card({ status: step.status, class: clsx(theme?.card, classes?.card) })} role="alert">
|
|
24
24
|
<div class={content({ class: clsx(theme?.content, classes?.content) })}>
|
package/dist/theme/themes.d.ts
CHANGED
package/dist/theme/themes.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// components
|
|
1
2
|
export { accordion, accordionItem } from "../accordion";
|
|
2
3
|
export { alert } from "../alert";
|
|
3
4
|
export { avatar } from "../avatar";
|
|
@@ -73,3 +74,5 @@ export { mark } from "../typography/mark";
|
|
|
73
74
|
export { paragraph } from "../typography/paragraph";
|
|
74
75
|
export { secondary } from "../typography/secondary";
|
|
75
76
|
export { span } from "../typography/span";
|
|
77
|
+
// extend
|
|
78
|
+
export { virtualList } from "../virtuallist";
|
package/dist/toast/Toast.svelte
CHANGED
|
@@ -3,12 +3,9 @@
|
|
|
3
3
|
import Popper from "../utils/Popper.svelte";
|
|
4
4
|
import { tooltip } from "./theme";
|
|
5
5
|
import type { TooltipProps, TriggeredToggleEvent } from "../types";
|
|
6
|
-
import { getTheme } from "../theme/themeUtils";
|
|
7
6
|
|
|
8
7
|
let { type = "dark", color = undefined, trigger = "hover", arrow = true, children, placement = "top", onbeforetoggle: _onbeforetoggle, class: className, isOpen = $bindable(false), ...restProps }: TooltipProps = $props();
|
|
9
8
|
|
|
10
|
-
const theme = getTheme("tooltip");
|
|
11
|
-
|
|
12
9
|
const base = $derived(tooltip({ color, type, class: clsx(className) }));
|
|
13
10
|
function onbeforetoggle(ev: TriggeredToggleEvent) {
|
|
14
11
|
// block all focusable elements inside the tooltip
|
package/dist/types.d.ts
CHANGED
|
@@ -72,6 +72,7 @@ import type { AndroidVariants, DefaultMockupVariants, DesktopVariants, IosVarian
|
|
|
72
72
|
import type { ApexOptions } from "apexcharts";
|
|
73
73
|
import type { ButtonToggleVariants } from "./forms/button-toggle/theme";
|
|
74
74
|
import type { TagsVariants } from "./forms/tags/theme";
|
|
75
|
+
import type { VirtualListVariants } from "./virtuallist/theme";
|
|
75
76
|
import type { CloseButtonVariants } from "./utils/theme";
|
|
76
77
|
import type { DialogVariants } from "./dialog/theme";
|
|
77
78
|
export declare const xs = "xs";
|
|
@@ -685,7 +686,7 @@ export interface InputAddonProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
685
686
|
children: Snippet;
|
|
686
687
|
size?: ButtonGroupProps["size"];
|
|
687
688
|
}
|
|
688
|
-
export interface PhoneInputProps
|
|
689
|
+
export interface PhoneInputProps extends PhoneInputVariants, Omit<HTMLInputAttributes, "size" | "children" | "value"> {
|
|
689
690
|
phoneType?: "default" | "floating" | "countryCode" | "copy" | "advanced";
|
|
690
691
|
children?: Snippet;
|
|
691
692
|
floatingLabel?: string;
|
|
@@ -1753,3 +1754,13 @@ export interface ArrowProps {
|
|
|
1753
1754
|
strategy?: "absolute" | "fixed";
|
|
1754
1755
|
class?: ClassValue | null;
|
|
1755
1756
|
}
|
|
1757
|
+
export interface VirtualListProps<T = unknown> extends VirtualListVariants, Omit<HTMLAttributes<HTMLDivElement>, "children"> {
|
|
1758
|
+
children: Snippet<[item: T, index: number]>;
|
|
1759
|
+
items?: T[];
|
|
1760
|
+
minItemHeight?: number;
|
|
1761
|
+
height?: number;
|
|
1762
|
+
overscan?: number;
|
|
1763
|
+
getItemHeight?: (item: T, index: number) => number;
|
|
1764
|
+
scrollToIndex?: (fn: (index: number) => void) => void;
|
|
1765
|
+
class?: ClassValue | null;
|
|
1766
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { VirtualListProps } from "../types";
|
|
3
|
+
import { virtualList } from "./theme";
|
|
4
|
+
import clsx from "clsx";
|
|
5
|
+
import { getTheme } from "../theme/themeUtils";
|
|
6
|
+
|
|
7
|
+
// Destructure props with defaults
|
|
8
|
+
let {
|
|
9
|
+
items = [],
|
|
10
|
+
minItemHeight = 50,
|
|
11
|
+
height = 400,
|
|
12
|
+
overscan = 5,
|
|
13
|
+
getItemHeight,
|
|
14
|
+
scrollToIndex, // Bind function to parent
|
|
15
|
+
children,
|
|
16
|
+
class: className,
|
|
17
|
+
classes
|
|
18
|
+
}: VirtualListProps = $props();
|
|
19
|
+
|
|
20
|
+
const theme = getTheme("virtualList");
|
|
21
|
+
|
|
22
|
+
let container: HTMLDivElement | undefined;
|
|
23
|
+
let scrollTop = $state(0);
|
|
24
|
+
let rafId: number | undefined;
|
|
25
|
+
|
|
26
|
+
const styles = virtualList();
|
|
27
|
+
|
|
28
|
+
// Total height of all items
|
|
29
|
+
const totalHeight = $derived.by(() => items.reduce((sum: number, item, i) => sum + (getItemHeight ? getItemHeight(item, i) : (minItemHeight ?? 50)), 0));
|
|
30
|
+
|
|
31
|
+
// Find the first visible index
|
|
32
|
+
const startIndex = $derived.by(() => {
|
|
33
|
+
let y = 0;
|
|
34
|
+
for (let i = 0; i < items.length; i++) {
|
|
35
|
+
const h = getItemHeight ? getItemHeight(items[i], i) : (minItemHeight ?? 50);
|
|
36
|
+
if (y + h > scrollTop) return Math.max(0, i - overscan);
|
|
37
|
+
y += h;
|
|
38
|
+
}
|
|
39
|
+
return 0;
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Find the last visible index
|
|
43
|
+
const endIndex = $derived.by(() => {
|
|
44
|
+
let y = 0;
|
|
45
|
+
for (let i = 0; i < items.length; i++) {
|
|
46
|
+
const h = getItemHeight ? getItemHeight(items[i], i) : (minItemHeight ?? 50);
|
|
47
|
+
y += h;
|
|
48
|
+
if (y >= scrollTop + height) return Math.min(items.length, i + overscan + 1);
|
|
49
|
+
}
|
|
50
|
+
return items.length;
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Items currently rendered
|
|
54
|
+
const visibleItems = $derived.by(() => items.slice(startIndex, endIndex));
|
|
55
|
+
|
|
56
|
+
// Offset of the first visible item
|
|
57
|
+
const offsetY = $derived.by(() => items.slice(0, startIndex).reduce((sum: number, item, i) => sum + (getItemHeight ? getItemHeight(item, i) : (minItemHeight ?? 50)), 0));
|
|
58
|
+
|
|
59
|
+
// Performance optimized scroll handler using RAF
|
|
60
|
+
function handleScroll() {
|
|
61
|
+
if (rafId) cancelAnimationFrame(rafId);
|
|
62
|
+
rafId = requestAnimationFrame(() => {
|
|
63
|
+
if (container) scrollTop = container.scrollTop;
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Scroll to specific index
|
|
68
|
+
function scrollToIndexImpl(index: number) {
|
|
69
|
+
if (!container || index < 0 || index >= items.length) return;
|
|
70
|
+
|
|
71
|
+
let y = 0;
|
|
72
|
+
for (let i = 0; i < index; i++) {
|
|
73
|
+
y += getItemHeight ? getItemHeight(items[i], i) : (minItemHeight ?? 50);
|
|
74
|
+
}
|
|
75
|
+
container.scrollTop = y;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Bind scrollToIndex function to parent component
|
|
79
|
+
$effect(() => {
|
|
80
|
+
if (scrollToIndex) {
|
|
81
|
+
scrollToIndex(scrollToIndexImpl);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Cleanup RAF on unmount
|
|
86
|
+
$effect(() => {
|
|
87
|
+
return () => {
|
|
88
|
+
if (rafId) cancelAnimationFrame(rafId);
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
</script>
|
|
92
|
+
|
|
93
|
+
<div bind:this={container} onscroll={handleScroll} role="list" aria-label="Virtual scrolling list" class={styles.container({ class: clsx(theme?.container, className) })} style={`height:${height}px; position:relative;`}>
|
|
94
|
+
<div class={styles.spacer({ class: clsx(theme?.spacer, classes?.spacer) })} style={`height:${totalHeight}px;`}>
|
|
95
|
+
<div class={styles.content({ class: clsx(theme?.content, classes?.content) })} style={`transform:translateY(${offsetY}px); will-change:transform;`}>
|
|
96
|
+
{#each visibleItems as item, i (startIndex + i)}
|
|
97
|
+
{@render children?.(item, startIndex + i)}
|
|
98
|
+
{/each}
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
|
|
103
|
+
<!--
|
|
104
|
+
@component
|
|
105
|
+
[Go to docs](https://flowbite-svelte.com/)
|
|
106
|
+
## Type
|
|
107
|
+
[VirtualListProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2048)
|
|
108
|
+
## Props
|
|
109
|
+
@prop items = []
|
|
110
|
+
@prop minItemHeight = 50
|
|
111
|
+
@prop height = 400
|
|
112
|
+
@prop overscan = 5
|
|
113
|
+
@prop getItemHeight
|
|
114
|
+
@prop scrollToIndex
|
|
115
|
+
@prop children
|
|
116
|
+
@prop class: className
|
|
117
|
+
@prop classes
|
|
118
|
+
-->
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { VirtualListProps } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* [Go to docs](https://flowbite-svelte.com/)
|
|
4
|
+
* ## Type
|
|
5
|
+
* [VirtualListProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2048)
|
|
6
|
+
* ## Props
|
|
7
|
+
* @prop items = []
|
|
8
|
+
* @prop minItemHeight = 50
|
|
9
|
+
* @prop height = 400
|
|
10
|
+
* @prop overscan = 5
|
|
11
|
+
* @prop getItemHeight
|
|
12
|
+
* @prop scrollToIndex
|
|
13
|
+
* @prop children
|
|
14
|
+
* @prop class: className
|
|
15
|
+
* @prop classes
|
|
16
|
+
*/
|
|
17
|
+
declare const VirtualList: import("svelte").Component<VirtualListProps<unknown>, {}, "">;
|
|
18
|
+
type VirtualList = ReturnType<typeof VirtualList>;
|
|
19
|
+
export default VirtualList;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type VariantProps } from "tailwind-variants";
|
|
2
|
+
import type { Classes } from "../theme/themeUtils";
|
|
3
|
+
export type VirtualListVariants = VariantProps<typeof virtualList> & Classes<typeof virtualList>;
|
|
4
|
+
export declare const virtualList: import("tailwind-variants").TVReturnType<{
|
|
5
|
+
[key: string]: {
|
|
6
|
+
[key: string]: import("tailwind-merge").ClassNameValue | {
|
|
7
|
+
container?: import("tailwind-merge").ClassNameValue;
|
|
8
|
+
content?: import("tailwind-merge").ClassNameValue;
|
|
9
|
+
spacer?: import("tailwind-merge").ClassNameValue;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
} | {
|
|
13
|
+
[x: string]: {
|
|
14
|
+
[x: string]: import("tailwind-merge").ClassNameValue | {
|
|
15
|
+
container?: import("tailwind-merge").ClassNameValue;
|
|
16
|
+
content?: import("tailwind-merge").ClassNameValue;
|
|
17
|
+
spacer?: import("tailwind-merge").ClassNameValue;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
} | {}, {
|
|
21
|
+
container: string;
|
|
22
|
+
spacer: string;
|
|
23
|
+
content: string;
|
|
24
|
+
}, undefined, {
|
|
25
|
+
[key: string]: {
|
|
26
|
+
[key: string]: import("tailwind-merge").ClassNameValue | {
|
|
27
|
+
container?: import("tailwind-merge").ClassNameValue;
|
|
28
|
+
content?: import("tailwind-merge").ClassNameValue;
|
|
29
|
+
spacer?: import("tailwind-merge").ClassNameValue;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
} | {}, {
|
|
33
|
+
container: string;
|
|
34
|
+
spacer: string;
|
|
35
|
+
content: string;
|
|
36
|
+
}, import("tailwind-variants").TVReturnType<unknown, {
|
|
37
|
+
container: string;
|
|
38
|
+
spacer: string;
|
|
39
|
+
content: string;
|
|
40
|
+
}, undefined, unknown, unknown, undefined>>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flowbite-svelte",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.19.1",
|
|
4
4
|
"description": "Flowbite components for Svelte",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"author": {
|
|
@@ -825,6 +825,10 @@
|
|
|
825
825
|
"types": "./dist/video/Video.svelte.d.ts",
|
|
826
826
|
"svelte": "./dist/video/Video.svelte"
|
|
827
827
|
},
|
|
828
|
+
"./VirtualList.svelte": {
|
|
829
|
+
"types": "./dist/virtuallist/VirtualList.svelte.d.ts",
|
|
830
|
+
"svelte": "./dist/virtuallist/VirtualList.svelte"
|
|
831
|
+
},
|
|
828
832
|
"./package.json": "./package.json"
|
|
829
833
|
},
|
|
830
834
|
"scripts": {
|