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.
@@ -25,7 +25,7 @@
25
25
 
26
26
  let ref: HTMLDivElement | undefined = $state(undefined);
27
27
 
28
- function close(event: MouseEvent) {
28
+ function close() {
29
29
  if (ref?.dispatchEvent(new Event("close", { bubbles: true, cancelable: true }))) {
30
30
  alertStatus = false;
31
31
  }
@@ -20,7 +20,7 @@
20
20
 
21
21
  let ref: HTMLDivElement | undefined = $state(undefined);
22
22
 
23
- const close = (ev: Event) => {
23
+ const close = () => {
24
24
  if (ref?.dispatchEvent(new Event("close", { bubbles: true, cancelable: true }))) {
25
25
  badgeStatus = false;
26
26
  }
@@ -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 = (node: HTMLElement) => {
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
- : (evt: MouseEvent | TouchEvent) => {
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 = (dlg: HTMLDialogElement) => (open = false);
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(ev.currentTarget);
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(dlg);
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(dlg);
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(ev: MouseEvent) {
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(event: Event) {
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(event: FocusEvent) {
115
+ function defaultHandleFocus() {
116
116
  isFocused = true;
117
117
  updateSuggestions();
118
118
  }
119
119
 
120
- function defaultHandleBlur(event: FocusEvent) {
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(event);
177
+ defaultHandleFocus();
178
178
  }
179
179
 
180
180
  function handleBlur(event: FocusEvent) {
181
181
  if (resolvedOnBlur) {
182
182
  resolvedOnBlur(event);
183
183
  }
184
- defaultHandleBlur(event);
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<number>, {}, "">;
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 on:scroll={checkDropdownPosition} on:resize={checkDropdownPosition} />
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} oninput={handleInput} bind:value={contents} placeholder={value.length === 0 ? placeholder : ""} type="text" autocomplete="off" class={inputCls({ class: clsx(styling.input) })} />
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
@@ -78,3 +78,4 @@ export * from "./typography/span";
78
78
  export * from "./video";
79
79
  export * from "./utils";
80
80
  export * from "./types";
81
+ export * from "./virtuallist";
package/dist/index.js CHANGED
@@ -83,3 +83,5 @@ export * from "./typography/span";
83
83
  export * from "./video";
84
84
  export * from "./utils";
85
85
  export * from "./types";
86
+ // extend
87
+ export * from "./virtuallist";
@@ -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, LinkType } from "..";
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> = (ev) => {
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, class: className, classes, articleClass, divClass, div2Class, div3Class, imgClass, ulClass, liClass }: ReviewProps = $props();
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
@@ -10,7 +10,6 @@ import type { ReviewProps } from "../types";
10
10
  * @prop item2
11
11
  * @prop item3
12
12
  * @prop review
13
- * @prop class: className
14
13
  * @prop classes
15
14
  * @prop articleClass
16
15
  * @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 step, i}
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, index}
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, index}
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) })}>
@@ -68,3 +68,4 @@ export { mark } from "../typography/mark";
68
68
  export { paragraph } from "../typography/paragraph";
69
69
  export { secondary } from "../typography/secondary";
70
70
  export { span } from "../typography/span";
71
+ export { virtualList } from "../virtuallist";
@@ -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";
@@ -30,7 +30,7 @@
30
30
 
31
31
  let ref: HTMLDivElement | undefined = $state(undefined);
32
32
 
33
- function _close(event: MouseEvent) {
33
+ function _close() {
34
34
  if (ref?.dispatchEvent(new Event("close", { bubbles: true, cancelable: true }))) {
35
35
  toastStatus = false;
36
36
  }
@@ -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<T extends InputValue = number> extends PhoneInputVariants, Omit<HTMLInputAttributes, "size" | "children" | "value"> {
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,2 @@
1
+ export { default as VirtualList } from "./VirtualList.svelte";
2
+ export { virtualList } from "./theme";
@@ -0,0 +1,2 @@
1
+ export { default as VirtualList } from "./VirtualList.svelte";
2
+ export { virtualList } from "./theme";
@@ -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>>;
@@ -0,0 +1,8 @@
1
+ import { tv } from "tailwind-variants";
2
+ export const virtualList = tv({
3
+ slots: {
4
+ container: "overflow-y-auto scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-transparent",
5
+ spacer: "relative",
6
+ content: "absolute top-0 left-0 right-0"
7
+ }
8
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flowbite-svelte",
3
- "version": "1.18.2",
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": {