virtua 0.51.3 → 0.52.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.
Files changed (46) hide show
  1. package/README.md +37 -13
  2. package/lib/angular/VGrid.d.ts +249 -0
  3. package/lib/angular/VList.d.ts +3 -3
  4. package/lib/angular/Virtualizer.d.ts +3 -3
  5. package/lib/angular/WindowVirtualizer.d.ts +3 -3
  6. package/lib/angular/index.d.ts +2 -0
  7. package/lib/angular/index.js +1150 -327
  8. package/lib/angular/index.js.map +1 -1
  9. package/lib/core/grid.d.ts +30 -0
  10. package/lib/core/index.cjs +484 -270
  11. package/lib/core/index.cjs.map +1 -1
  12. package/lib/core/index.d.ts +5 -3
  13. package/lib/core/index.js +462 -249
  14. package/lib/core/index.js.map +1 -1
  15. package/lib/core/layouts/grid.d.ts +21 -0
  16. package/lib/core/scroll-to.d.ts +50 -1
  17. package/lib/core/types.d.ts +0 -25
  18. package/lib/index.cjs +761 -558
  19. package/lib/index.cjs.map +1 -1
  20. package/lib/index.d.ts +2 -1
  21. package/lib/index.js +730 -509
  22. package/lib/index.js.map +1 -1
  23. package/lib/react/VGrid.d.ts +105 -80
  24. package/lib/react/index.d.ts +3 -2
  25. package/lib/solid/VGrid.d.ts +193 -0
  26. package/lib/solid/index.cjs +817 -288
  27. package/lib/solid/index.cjs.map +1 -1
  28. package/lib/solid/index.d.ts +3 -0
  29. package/lib/solid/index.js +786 -270
  30. package/lib/solid/index.js.map +1 -1
  31. package/lib/solid/index.jsx +743 -124
  32. package/lib/solid/index.jsx.map +1 -1
  33. package/lib/svelte/GridCell.svelte +44 -0
  34. package/lib/svelte/GridRow.svelte +42 -0
  35. package/lib/svelte/GridRowGroup.svelte +42 -0
  36. package/lib/svelte/VGrid.svelte +238 -0
  37. package/lib/svelte/VGrid.type.d.ts +185 -0
  38. package/lib/svelte/index.d.ts +3 -0
  39. package/lib/svelte/index.js +2 -1
  40. package/lib/vue/VGrid.d.ts +194 -0
  41. package/lib/vue/index.cjs +886 -376
  42. package/lib/vue/index.cjs.map +1 -1
  43. package/lib/vue/index.d.ts +3 -0
  44. package/lib/vue/index.js +858 -349
  45. package/lib/vue/index.js.map +1 -1
  46. package/package.json +4 -3
@@ -0,0 +1,44 @@
1
+ <script lang="ts" generics="R, C">
2
+ import { type Snippet } from "svelte";
3
+ import {
4
+ type GridCellState,
5
+ type GridDriver,
6
+ type VGridCell,
7
+ gridStyleToString,
8
+ } from "../core/index.js";
9
+
10
+ interface Props {
11
+ state: GridCellState;
12
+ children: Snippet<[row: R, col: C, cell: Readonly<VGridCell>]>;
13
+ row: R;
14
+ col: C;
15
+ rowIndex: number;
16
+ resizer: GridDriver["$observeItem"];
17
+ }
18
+
19
+ let { state, children, row, col, rowIndex, resizer }: Props = $props();
20
+
21
+ let elementRef: HTMLDivElement;
22
+
23
+ // Derived, so that a new state with the same indexes is a no-op.
24
+ let measureRowIndex = $derived(state.$measureRow);
25
+ let measureColIndex = $derived(state.$measureCol);
26
+ $effect(() => {
27
+ if (measureRowIndex == null && measureColIndex == null) return;
28
+ return resizer(elementRef, measureRowIndex, measureColIndex);
29
+ });
30
+
31
+ let style: string = $derived(gridStyleToString(state.$style));
32
+ </script>
33
+
34
+ <div
35
+ bind:this={elementRef}
36
+ role={state.$role}
37
+ aria-colindex={state.$col + 1}
38
+ aria-rowspan={state.$rowSpan}
39
+ aria-colspan={state.$colSpan}
40
+ aria-sort={state.$sort}
41
+ {style}
42
+ >
43
+ {@render children(row, col, { rowIndex, colIndex: state.$col })}
44
+ </div>
@@ -0,0 +1,42 @@
1
+ <script lang="ts" generics="R, C">
2
+ import { type Snippet } from "svelte";
3
+ import {
4
+ getAxisItem,
5
+ getAxisLength,
6
+ type GridDriver,
7
+ type GridRowState,
8
+ type VGridAxis,
9
+ type VGridCell,
10
+ gridStyleToString,
11
+ } from "../core/index.js";
12
+ import GridCell from "./GridCell.svelte";
13
+
14
+ interface Props {
15
+ state: GridRowState;
16
+ children: Snippet<[row: R, col: C, cell: Readonly<VGridCell>]>;
17
+ row: R;
18
+ cols: VGridAxis<C>;
19
+ resizer: GridDriver["$observeItem"];
20
+ }
21
+
22
+ let { state, children, row, cols, resizer }: Props = $props();
23
+
24
+ let style: string = $derived(gridStyleToString(state.$style));
25
+ </script>
26
+
27
+ <div role="row" aria-rowindex={state.$row + 1} {style}>
28
+ {#each state.$cells as cell (cell.$col)}
29
+ <!-- Guard for experimental.async: true, which runs the each block before $effect.pre -->
30
+ <!-- https://github.com/inokawa/virtua/pull/847 -->
31
+ {#if cell.$col < getAxisLength(cols)}
32
+ <GridCell
33
+ state={cell}
34
+ {children}
35
+ {row}
36
+ col={getAxisItem(cols, cell.$col)}
37
+ rowIndex={state.$row}
38
+ {resizer}
39
+ />
40
+ {/if}
41
+ {/each}
42
+ </div>
@@ -0,0 +1,42 @@
1
+ <script lang="ts" generics="R, C">
2
+ import { type Snippet } from "svelte";
3
+ import {
4
+ getAxisItem,
5
+ getAxisLength,
6
+ type GridDriver,
7
+ type GridRowGroupState,
8
+ type VGridAxis,
9
+ type VGridCell,
10
+ gridStyleToString,
11
+ } from "../core/index.js";
12
+ import GridRow from "./GridRow.svelte";
13
+
14
+ interface Props {
15
+ state: GridRowGroupState;
16
+ children: Snippet<[row: R, col: C, cell: Readonly<VGridCell>]>;
17
+ rows: VGridAxis<R>;
18
+ cols: VGridAxis<C>;
19
+ resizer: GridDriver["$observeItem"];
20
+ }
21
+
22
+ let { state, children, rows, cols, resizer }: Props = $props();
23
+
24
+ let style: string = $derived(gridStyleToString(state.$style));
25
+ </script>
26
+
27
+ <!-- https://www.w3.org/TR/wai-aria-1.2/#rowgroup -->
28
+ <div role="rowgroup" {style}>
29
+ {#each state.$rows as row (row.$row)}
30
+ <!-- Guard for experimental.async: true, which runs the each block before $effect.pre -->
31
+ <!-- https://github.com/inokawa/virtua/pull/847 -->
32
+ {#if row.$row < getAxisLength(rows)}
33
+ <GridRow
34
+ state={row}
35
+ {children}
36
+ row={getAxisItem(rows, row.$row)}
37
+ {cols}
38
+ {resizer}
39
+ />
40
+ {/if}
41
+ {/each}
42
+ </div>
@@ -0,0 +1,238 @@
1
+ <script lang="ts" generics="R = number, C = number">
2
+ import { onMount, onDestroy } from "svelte";
3
+ import {
4
+ type StateVersion,
5
+ UPDATE_SCROLL_END_EVENT,
6
+ UPDATE_SCROLL_EVENT,
7
+ UPDATE_VIRTUAL_STATE,
8
+ createContainerGridDriver,
9
+ createGridLayout,
10
+ createGridPlan,
11
+ createVirtualStore,
12
+ getAxisItem,
13
+ getAxisLength,
14
+ getScrollSize,
15
+ gridScrollBy,
16
+ gridScrollTo,
17
+ gridScrollToIndex,
18
+ updateGridAxis,
19
+ } from "../core/index.js";
20
+ import { styleToString } from "./utils.js";
21
+ import GridRow from "./GridRow.svelte";
22
+ import GridRowGroup from "./GridRowGroup.svelte";
23
+ import type { VGridHandle, VGridProps } from "./VGrid.type.js";
24
+
25
+ interface Props extends VGridProps<R, C> {}
26
+
27
+ let {
28
+ children,
29
+ rows,
30
+ cols,
31
+ rowHeight,
32
+ colWidth,
33
+ headerRows,
34
+ sectionRows,
35
+ footerRows,
36
+ headerCols,
37
+ footerCols,
38
+ spans,
39
+ keepMounted,
40
+ bufferSize,
41
+ gap = 0,
42
+ ariaSort,
43
+ onverticalscroll,
44
+ onhorizontalscroll,
45
+ onscrollend,
46
+ ...rest
47
+ }: Props = $props();
48
+
49
+ const rowLayout = createGridLayout(rows, rowHeight, gap);
50
+ const colLayout = createGridLayout(cols, colWidth, gap);
51
+ const rowStore = createVirtualStore(rowLayout);
52
+ const colStore = createVirtualStore(colLayout);
53
+ const driver = createContainerGridDriver(rowStore, colStore);
54
+
55
+ let containerRef: HTMLDivElement | undefined = $state();
56
+
57
+ let stateVersion: StateVersion = $state(
58
+ rowStore.$getStateVersion() + colStore.$getStateVersion(),
59
+ );
60
+ const rerender = () => {
61
+ stateVersion = rowStore.$getStateVersion() + colStore.$getStateVersion();
62
+ };
63
+ rowStore.$subscribe(UPDATE_VIRTUAL_STATE, rerender);
64
+ colStore.$subscribe(UPDATE_VIRTUAL_STATE, rerender);
65
+
66
+ // Both stores observe both axes, so the end is notified once after both have ended.
67
+ let scrolled = false;
68
+ rowStore.$subscribe(UPDATE_SCROLL_EVENT, () => {
69
+ scrolled = true;
70
+ onverticalscroll && onverticalscroll(rowStore.$getScrollOffset());
71
+ });
72
+ colStore.$subscribe(UPDATE_SCROLL_EVENT, () => {
73
+ scrolled = true;
74
+ onhorizontalscroll && onhorizontalscroll(colStore.$getScrollOffset());
75
+ });
76
+ const notifyScrollEnd = () => {
77
+ if (scrolled && !rowStore.$isScrolling() && !colStore.$isScrolling()) {
78
+ scrolled = false;
79
+ onscrollend && onscrollend();
80
+ }
81
+ };
82
+ rowStore.$subscribe(UPDATE_SCROLL_END_EVENT, notifyScrollEnd);
83
+ colStore.$subscribe(UPDATE_SCROLL_END_EVENT, notifyScrollEnd);
84
+
85
+ // The sizes read from the items are tracked, so the items mutated in place are followed.
86
+ $effect.pre(() => {
87
+ updateGridAxis(rowStore, rowLayout, rows, rowHeight, true);
88
+ });
89
+ $effect.pre(() => {
90
+ updateGridAxis(colStore, colLayout, cols, colWidth, true);
91
+ });
92
+ let rowCount = $derived(stateVersion && rowStore.$getItemsLength());
93
+ let colCount = $derived(stateVersion && colStore.$getItemsLength());
94
+ let plan = $derived.by(() => {
95
+ stateVersion;
96
+ return createGridPlan(
97
+ rowLayout,
98
+ colLayout,
99
+ rowStore.$getRange(bufferSize),
100
+ colStore.$getRange(bufferSize),
101
+ headerRows,
102
+ sectionRows,
103
+ footerRows,
104
+ headerCols,
105
+ footerCols,
106
+ spans,
107
+ keepMounted,
108
+ ariaSort,
109
+ );
110
+ });
111
+ let isScrolling = $derived(
112
+ stateVersion && (rowStore.$isScrolling() || colStore.$isScrolling()),
113
+ );
114
+
115
+ onMount(() => {
116
+ driver.$observe(containerRef!);
117
+ });
118
+ onDestroy(() => {
119
+ rowStore.$dispose();
120
+ colStore.$dispose();
121
+ driver.$dispose();
122
+ });
123
+
124
+ let prevStateVersion: StateVersion | undefined;
125
+ $effect(() => {
126
+ if (prevStateVersion === stateVersion) return;
127
+ prevStateVersion = stateVersion;
128
+ driver.$effect();
129
+ });
130
+
131
+ export const getVerticalScrollOffset: VGridHandle["getVerticalScrollOffset"] =
132
+ rowStore.$getScrollOffset;
133
+ export const getHorizontalScrollOffset: VGridHandle["getHorizontalScrollOffset"] =
134
+ colStore.$getScrollOffset;
135
+ export const getScrollHeight: VGridHandle["getScrollHeight"] = () =>
136
+ getScrollSize(rowStore);
137
+ export const getScrollWidth: VGridHandle["getScrollWidth"] = () =>
138
+ getScrollSize(colStore);
139
+ export const getViewportHeight: VGridHandle["getViewportHeight"] =
140
+ rowStore.$getViewportSize;
141
+ export const getViewportWidth: VGridHandle["getViewportWidth"] =
142
+ colStore.$getViewportSize;
143
+ export const findRowIndex: VGridHandle["findRowIndex"] =
144
+ rowStore.$findItemIndex;
145
+ export const findColIndex: VGridHandle["findColIndex"] =
146
+ colStore.$findItemIndex;
147
+ export const getRowOffset: VGridHandle["getRowOffset"] =
148
+ rowStore.$getItemOffset;
149
+ export const getColOffset: VGridHandle["getColOffset"] =
150
+ colStore.$getItemOffset;
151
+ export const getRowSize: VGridHandle["getRowSize"] = rowStore.$getItemSize;
152
+ export const getColSize: VGridHandle["getColSize"] = colStore.$getItemSize;
153
+ export const scrollToIndex: VGridHandle["scrollToIndex"] = (opts) =>
154
+ gridScrollToIndex(
155
+ driver,
156
+ rowStore,
157
+ colStore,
158
+ headerRows,
159
+ sectionRows,
160
+ footerRows,
161
+ headerCols,
162
+ footerCols,
163
+ opts,
164
+ );
165
+ export const scrollTo: VGridHandle["scrollTo"] = ({ vertical, horizontal }) =>
166
+ gridScrollTo(driver, vertical, horizontal);
167
+ export const scrollBy: VGridHandle["scrollBy"] = ({ vertical, horizontal }) =>
168
+ gridScrollBy(driver, rowStore, colStore, vertical, horizontal);
169
+
170
+ const viewportStyle = styleToString({
171
+ overflow: "auto",
172
+ contain: "strict",
173
+ width: "100%",
174
+ height: "100%",
175
+ });
176
+ let containerStyle = $derived.by(() => {
177
+ const { $rowTemplate: rowTemplate, $colTemplate: colTemplate } = plan;
178
+ // A jump deferred during scrolling shifts the tracks, as it shifts the items of the lists.
179
+ const marginTop = rowStore.$getItemOffset(0);
180
+ const marginInlineStart = colStore.$getItemOffset(0);
181
+ return styleToString({
182
+ // https://github.com/inokawa/virtua/pull/775 https://github.com/inokawa/virtua/issues/800
183
+ contain: "size style",
184
+ "overflow-anchor": "none", // opt out browser's scroll anchoring because it will conflict to scroll anchoring of virtualizer
185
+ flex: "none", // flex style can break layout
186
+ display: "grid",
187
+ "grid-template-rows": rowTemplate,
188
+ "grid-template-columns": colTemplate,
189
+ gap: gap + "px",
190
+ "margin-top": marginTop + "px",
191
+ "margin-inline-start": marginInlineStart + "px",
192
+ // The width is left to the viewport, so the auto columns fill it as the columns of a table.
193
+ height: getScrollSize(rowStore) - marginTop + "px",
194
+ "pointer-events": isScrolling ? "none" : undefined,
195
+ });
196
+ });
197
+ </script>
198
+
199
+ <!--
200
+ @component
201
+ Virtualized grid component for tabular data. See {@link VGridProps} and {@link VGridHandle}.
202
+ -->
203
+ <!-- https://www.w3.org/WAI/ARIA/apg/patterns/table/ -->
204
+ <!-- https://www.w3.org/TR/wai-aria-1.2/#table -->
205
+ <!-- https://www.w3.org/TR/wai-aria-1.2/#aria-rowcount -->
206
+ <div
207
+ role="table"
208
+ aria-rowcount={rowCount}
209
+ aria-colcount={colCount}
210
+ {...rest}
211
+ style="{viewportStyle} {rest.style || ''}"
212
+ >
213
+ <div bind:this={containerRef} style={containerStyle}>
214
+ {#each plan.$groups as state ("$rows" in state ? state.$key : state.$row)}
215
+ {#if "$rows" in state}
216
+ <GridRowGroup
217
+ {state}
218
+ {children}
219
+ {rows}
220
+ {cols}
221
+ resizer={driver.$observeItem}
222
+ />
223
+ {:else}
224
+ <!-- Guard for experimental.async: true, which runs the each block before $effect.pre -->
225
+ <!-- https://github.com/inokawa/virtua/pull/847 -->
226
+ {#if state.$row < getAxisLength(rows)}
227
+ <GridRow
228
+ {state}
229
+ {children}
230
+ row={getAxisItem(rows, state.$row)}
231
+ {cols}
232
+ resizer={driver.$observeItem}
233
+ />
234
+ {/if}
235
+ {/if}
236
+ {/each}
237
+ </div>
238
+ </div>
@@ -0,0 +1,185 @@
1
+ import { Snippet } from 'svelte';
2
+ import { VGridScrollToIndexOpts, VGridAxis, VGridCell, VGridSize, VGridSpan } from '../core/index.js';
3
+ import { ViewportComponentAttributes } from './types.js';
4
+ /**
5
+ * Props of {@link VGrid}.
6
+ */
7
+ export interface VGridProps<R = number, C = number> extends Omit<ViewportComponentAttributes, "role"> {
8
+ /**
9
+ * A snippet to create cell elements rendered by this component.
10
+ * @param row the item of {@link VGridProps.rows} at the row of the cell, or the row index if {@link VGridProps.rows} is a number
11
+ * @param col the item of {@link VGridProps.cols} at the column of the cell, or the column index if {@link VGridProps.cols} is a number
12
+ * @param cell the row index and the column index of the cell
13
+ */
14
+ children: Snippet<[row: R, col: C, cell: Readonly<VGridCell>]>;
15
+ /**
16
+ * The rows of the grid. See {@link VGridAxis} for the accepted values.
17
+ */
18
+ rows: VGridAxis<R>;
19
+ /**
20
+ * The columns of the grid. See {@link VGridAxis} for the accepted values.
21
+ */
22
+ cols: VGridAxis<C>;
23
+ /**
24
+ * The heights of the rows. See {@link VGridSize} for the accepted values.
25
+ */
26
+ rowHeight: NoInfer<VGridSize<R>>;
27
+ /**
28
+ * The widths of the columns. See {@link VGridSize} for the accepted values.
29
+ */
30
+ colWidth: NoInfer<VGridSize<C>>;
31
+ /**
32
+ * The number of the leading rows pinned to the start, which are the column headers (`role="columnheader"`).
33
+ *
34
+ * **The pinned cells are rendered over the other cells, so give them an opaque background.**
35
+ * @defaultValue 0
36
+ */
37
+ headerRows?: number;
38
+ /**
39
+ * Indexes of the rows which start sections. A section lasts until the next section row or the footer rows, and its first row sticks below the header rows while the section is scrolled through.
40
+ *
41
+ * **The section rows are rendered over the other cells while they stick, so give them an opaque background.**
42
+ */
43
+ sectionRows?: readonly number[];
44
+ /**
45
+ * The number of the trailing rows pinned to the end.
46
+ *
47
+ * **The pinned cells are rendered over the other cells, so give them an opaque background.**
48
+ * @defaultValue 0
49
+ */
50
+ footerRows?: number;
51
+ /**
52
+ * The number of the leading columns pinned to the start, the last of which is the row header (`role="rowheader"`).
53
+ *
54
+ * **The pinned cells are rendered over the other cells, so give them an opaque background.**
55
+ * @defaultValue 0
56
+ */
57
+ headerCols?: number;
58
+ /**
59
+ * The number of the trailing columns pinned to the end.
60
+ *
61
+ * **The pinned cells are rendered over the other cells, so give them an opaque background.**
62
+ * @defaultValue 0
63
+ */
64
+ footerCols?: number;
65
+ /**
66
+ * Cells merged over multiple rows and/or columns. See {@link VGridSpan} for the accepted values.
67
+ *
68
+ * The cell at the origin is stretched over the merged area, and the other cells in it are not rendered. Spans must not overlap each other or cross the boundaries of the pinned rows/columns or the sections. A spanning cell is not measured for `"auto"` sizes on the axes it spans, and doesn't enlarge those tracks.
69
+ */
70
+ spans?: readonly VGridSpan[];
71
+ /**
72
+ * List of cells that should be always mounted, even when off screen.
73
+ */
74
+ keepMounted?: readonly VGridCell[];
75
+ /**
76
+ * Extra space in pixels to render before/after the viewport. The minimum value is 0. Lower value will give better performance but you can increase to avoid showing blank cells in fast scrolling.
77
+ * @defaultValue 200
78
+ */
79
+ bufferSize?: number;
80
+ /**
81
+ * The gap between the rows and the columns in pixels, which is not included in the sizes. Must not be changed after mount.
82
+ * @defaultValue 0
83
+ */
84
+ gap?: number;
85
+ /**
86
+ * The header cell of the sorted column or row, and the sort order (`aria-sort`).
87
+ */
88
+ ariaSort?: VGridCell & {
89
+ order: "ascending" | "descending" | "other";
90
+ };
91
+ /**
92
+ * Callback invoked whenever the vertical scroll offset changes.
93
+ * @param offset Current scrollTop.
94
+ */
95
+ onverticalscroll?: (offset: number) => void;
96
+ /**
97
+ * Callback invoked whenever the horizontal scroll offset changes.
98
+ * @param offset Current scrollLeft. Always positive even in RTL.
99
+ */
100
+ onhorizontalscroll?: (offset: number) => void;
101
+ /**
102
+ * Callback invoked when scrolling stops.
103
+ */
104
+ onscrollend?: () => void;
105
+ }
106
+ /**
107
+ * Methods of {@link VGrid}.
108
+ */
109
+ export interface VGridHandle {
110
+ /**
111
+ * Get current scrollTop.
112
+ */
113
+ getVerticalScrollOffset(): number;
114
+ /**
115
+ * Get current scrollLeft. Always positive even in RTL.
116
+ */
117
+ getHorizontalScrollOffset(): number;
118
+ /**
119
+ * Get current scrollHeight.
120
+ */
121
+ getScrollHeight(): number;
122
+ /**
123
+ * Get current scrollWidth.
124
+ */
125
+ getScrollWidth(): number;
126
+ /**
127
+ * Get current clientHeight.
128
+ */
129
+ getViewportHeight(): number;
130
+ /**
131
+ * Get current clientWidth.
132
+ */
133
+ getViewportWidth(): number;
134
+ /**
135
+ * Find nearest row index from offset.
136
+ * @param offset offset in pixels from the top of the scroll container
137
+ */
138
+ findRowIndex(offset: number): number;
139
+ /**
140
+ * Find nearest column index from offset.
141
+ * @param offset offset in pixels from the start of the scroll container
142
+ */
143
+ findColIndex(offset: number): number;
144
+ /**
145
+ * Get offset of the row from the top.
146
+ * @param index index of row
147
+ */
148
+ getRowOffset(index: number): number;
149
+ /**
150
+ * Get offset of the column from the start.
151
+ * @param index index of column
152
+ */
153
+ getColOffset(index: number): number;
154
+ /**
155
+ * Get size of the row.
156
+ * @param index index of row
157
+ */
158
+ getRowSize(index: number): number;
159
+ /**
160
+ * Get size of the column.
161
+ * @param index index of column
162
+ */
163
+ getColSize(index: number): number;
164
+ /**
165
+ * Scroll to the cell specified by the indexes. The cell is not hidden behind the rows and the columns sticking over it.
166
+ * @param opts the indexes of the cell and the options. See {@link VGridScrollToIndexOpts}.
167
+ */
168
+ scrollToIndex(opts: VGridScrollToIndexOpts): void;
169
+ /**
170
+ * Scroll to the given offsets from the top/start of the scroll container.
171
+ * @param offset the offsets. The axis whose offset is omitted is not scrolled.
172
+ */
173
+ scrollTo(offset: {
174
+ vertical?: number;
175
+ horizontal?: number;
176
+ }): void;
177
+ /**
178
+ * Scroll by the given offsets from the current position.
179
+ * @param offset the offsets. The axis whose offset is omitted is not scrolled.
180
+ */
181
+ scrollBy(offset: {
182
+ vertical?: number;
183
+ horizontal?: number;
184
+ }): void;
185
+ }
@@ -7,3 +7,6 @@ export { default as Virtualizer } from './Virtualizer.svelte';
7
7
  export type { VirtualizerProps, VirtualizerHandle, } from './Virtualizer.type.js';
8
8
  export { default as WindowVirtualizer } from './WindowVirtualizer.svelte';
9
9
  export type { WindowVirtualizerProps, WindowVirtualizerHandle, } from './WindowVirtualizer.type.js';
10
+ export { default as VGrid } from './VGrid.svelte';
11
+ export type { VGridProps, VGridHandle } from './VGrid.type.js';
12
+ export type { VGridSize, VGridSpan } from '../core/index.js';
@@ -1,4 +1,5 @@
1
1
  import VList from "./VList.svelte";
2
2
  import Virtualizer from "./Virtualizer.svelte";
3
3
  import WindowVirtualizer from "./WindowVirtualizer.svelte";
4
- export { VList, Virtualizer, WindowVirtualizer };
4
+ import VGrid from "./VGrid.svelte";
5
+ export { VGrid, VList, Virtualizer, WindowVirtualizer };