Types #
TypeScript type definitions for vlist — items, configuration, state, events, and the public API.
Public API #
The instance returned by .build(). Always-available methods are required properties. Feature methods are optional — they exist only when the corresponding feature is registered via .use().
VList #
interface VList<T extends VListItem = VListItem> {
// Properties
readonly element: HTMLElement
readonly items: readonly T[]
readonly total: number
// Data methods (always available)
setItems: (items: T[]) => void
appendItems: (items: T[]) => void
prependItems: (items: T[]) => void
updateItem: (index: number, updates: Partial<T>) => void
removeItem: (id: string | number) => boolean
getItemAt: (index: number) => T | undefined
getIndexById: (id: string | number) => number
reload: (options?: ReloadOptions) => Promise<void>
// Scroll methods (always available)
scrollToIndex: (index: number, alignOrOptions?: 'start' | 'center' | 'end' | ScrollToOptions) => void
cancelScroll: () => void
getScrollPosition: () => number
// Events (always available)
on: <K extends keyof VListEvents<T>>(event: K, handler: EventHandler<VListEvents<T>[K]>) => Unsubscribe
off: <K extends keyof VListEvents<T>>(event: K, handler: EventHandler<VListEvents<T>[K]>) => void
// Lifecycle
destroy: () => void
// Feature methods (present only when feature is registered)
select?: (...ids: Array<string | number>) => void
deselect?: (...ids: Array<string | number>) => void
toggleSelect?: (id: string | number) => void
selectAll?: () => void
clearSelection?: () => void
getSelected?: () => Array<string | number>
getSelectedItems?: () => T[]
selectNext?: () => void
selectPrevious?: () => void
getScrollSnapshot?: () => ScrollSnapshot
restoreScroll?: (snapshot: ScrollSnapshot) => void
updateGrid?: (config: { columns?: number; gap?: number }) => void
// Extensible — features add arbitrary methods
[key: string]: unknown
}
Always available:
- Data:
setItems,appendItems,prependItems,updateItem,removeItem,getItemAt,getIndexById,reload - Scroll:
scrollToIndex,cancelScroll,getScrollPosition - Events:
on,off - Lifecycle:
destroy
Added by features:
select,deselect,toggleSelect,selectAll,clearSelection,getSelected,getSelectedItems— added bywithSelectiongetScrollSnapshot,restoreScroll— added bywithSnapshotsreload(options?)— enhanced bywithAsync(acceptsReloadOptionswithsnapshotfor automatic scroll restore)
Note: There is no
scrollToItem(id)method. If you need to scroll to an item by ID, maintain your ownid → indexmap and callscrollToIndex.
Item Types #
The base constraint for all list data. The only requirement is a unique id — add any fields your template needs.
VListItem #
interface VListItem {
id: string | number
[key: string]: unknown
}
Requirements:
idmust be unique within the list- Can have any additional properties
interface User extends VListItem {
id: string
name: string
email: string
}
Configuration Types #
Configuration interfaces — from top-level BuilderConfig down to item sizing, scroll behavior, and scrollbar options.
BuilderConfig #
Top-level configuration object passed to vlist().
interface BuilderConfig<T extends VListItem = VListItem> {
container: HTMLElement | string
item: ItemConfig<T>
items?: T[]
overscan?: number
classPrefix?: string
ariaLabel?: string
orientation?: 'vertical' | 'horizontal'
padding?: number | [number, number] | [number, number, number, number]
reverse?: boolean
interactive?: boolean
focusOnClick?: boolean
scroll?: ScrollConfig
}
| Property | Type | Default | Description |
|---|---|---|---|
container |
HTMLElement | string |
— | Required. Container element or CSS selector. |
item |
ItemConfig<T> |
— | Required. Item sizing and template. |
items |
T[] |
[] |
Static items array. Omit when using withAsync. |
overscan |
number |
3 |
Extra items rendered outside the viewport in each direction. |
classPrefix |
string |
'vlist' |
CSS class prefix for all internal elements. |
ariaLabel |
string |
— | Sets aria-label on the root listbox element. |
orientation |
'vertical' | 'horizontal' |
'vertical' |
Scroll axis. |
padding |
number | [number, number] | [number, number, number, number] |
0 |
Padding around the list content. Works like CSS padding — adds inset space between the viewport edge and items. Follows CSS shorthand: number (all sides), [v, h] (vertical/horizontal), or [top, right, bottom, left]. Applied as CSS padding on .vlist-content with border-box. Works with list, grid, and masonry. Grid/masonry automatically subtract cross-axis padding from the container width for column calculations. |
reverse |
boolean |
false |
Bottom-anchored mode — list starts scrolled to the bottom. |
interactive |
boolean |
true |
Enable built-in keyboard navigation following the WAI-ARIA listbox pattern. |
focusOnClick |
boolean |
false |
Show focus ring on mouse click. Applies to baseline single-select. When using withSelection(), pass focusOnClick in its config instead. |
scroll |
ScrollConfig |
— | Fine-grained scroll behavior options. |
VListConfig #
Extended configuration used by framework adapters (React, Vue, Svelte, SolidJS). Inherits all BuilderConfig fields and adds convenience fields that adapters translate into .use(withX()) calls automatically.
interface VListConfig<T extends VListItem = VListItem>
extends Omit<BuilderConfig<T>, 'scroll'> {
scroll?: BuilderConfig['scroll'] & { scrollbar?: 'native' | 'none' | ScrollbarOptions }
layout?: 'list' | 'grid' | 'masonry'
grid?: GridConfig
masonry?: MasonryConfig
adapter?: VListAdapter<T>
loading?: { cancelThreshold?: number; preloadThreshold?: number; preloadAhead?: number }
groups?: GroupsConfig
selection?: SelectionConfig
scrollbar?: 'native' | 'none' | ScrollbarOptions
}
| Property | Type | Triggers | Description |
|---|---|---|---|
layout |
'list' | 'grid' | 'masonry' |
— | Layout mode. Set to 'grid' or 'masonry' with corresponding config. |
grid |
GridConfig |
withGrid() |
Grid columns and gap. Only used when layout is 'grid'. |
masonry |
MasonryConfig |
withMasonry() |
Masonry columns and gap. Only used when layout is 'masonry'. |
adapter |
VListAdapter<T> |
withAsync() |
Async data source. Omit items when using an adapter. |
loading |
object |
— | Loading behavior passed to withAsync(). |
groups |
GroupsConfig |
withGroups() |
Group items with sticky/inline headers. |
selection |
SelectionConfig |
withSelection() |
Item selection mode and initial state. |
scrollbar |
'native' | 'none' | ScrollbarOptions |
withScrollbar() |
Top-level scrollbar shorthand. |
scroll.scrollbar |
'native' | 'none' | ScrollbarOptions |
withScrollbar() |
Same as top-level scrollbar, nested under scroll. |
Each adapter defines its own config type as Omit<VListConfig<T>, 'container'> — the full config without container, since the adapter handles container binding. See Framework Adapters for per-framework details.
ItemConfig #
Controls how items are sized and rendered. Supports two sizing strategies — known sizes (Mode A) and auto-measurement (Mode B).
interface ItemConfig<T extends VListItem = VListItem> {
height?: number | ((index: number, context?: GridSizeContext) => number)
width?: number | ((index: number) => number)
estimatedHeight?: number
estimatedWidth?: number
gap?: number
striped?: boolean | "data" | "even" | "odd"
template: ItemTemplate<T>
}
| Property | Type | Default | Description |
|---|---|---|---|
height |
number | (index, ctx?) => number |
— | Item size in pixels along the main axis. Required for vertical lists. In grid mode, the function receives a GridSizeContext as a second argument. |
width |
number | (index) => number |
— | Item size for horizontal lists (orientation: 'horizontal'). Ignored in vertical mode. |
estimatedHeight |
number |
— | Estimated size for auto-measurement (Mode B). Requires .use(withAutoSize()). Items are rendered at this size, measured via ResizeObserver, and the real size is cached. Ignored if height is also set. |
estimatedWidth |
number |
— | Horizontal equivalent of estimatedHeight. Requires .use(withAutoSize()). Ignored if width is also set. |
gap |
number |
0 |
Gap between items in pixels along the main axis. Baked into the size cache (slot = itemSize + gap) and subtracted from the DOM element size, so items are positioned with precise spacing. The trailing gap after the last item is automatically removed. Works with fixed sizes, variable sizes, and auto-measurement (Mode B). Ignored when withGrid or withMasonry is active — those features manage their own gap. |
striped |
boolean | "data" | "even" | "odd" |
false |
Toggles .vlist-item--odd class for zebra-stripe styling. true counts all items (including group headers). "data" excludes group headers from the count (continuous across groups). "even" resets the counter after each group header — first data row is always even/non-striped (macOS Finder behavior). "odd" same reset but first data row is odd/striped. Without withGroups, all string modes behave like true. See Groups — Striped Rows. |
template |
ItemTemplate<T> |
— | Required. Render function for each visible item. |
Mode A — Known sizes. Use when you can derive size from data alone. Zero measurement overhead.
// Fixed — all items 48px
item: { height: 48, template: renderRow }
// Variable — derive size from data
item: {
height: (index) => data[index].type === 'header' ? 64 : 48,
template: renderRow,
}
Mode B — Auto-measurement. Use when size depends on rendered content (variable-length text, images with unknown aspect ratios). You provide an estimate and add the withAutoSize() feature; vlist measures actual DOM size, caches the result, and adjusts scroll position.
import { vlist, withAutoSize } from 'vlist';
vlist({
container: '#app',
item: {
estimatedHeight: 120,
template: (post) => `<article>${post.text}</article>`,
},
items: posts,
})
.use(withAutoSize())
.build();
Precedence: If both height and estimatedHeight are set, height wins (Mode A).
GridSizeContext #
Context provided to the size function in grid mode. Passed as the second argument to ItemConfig.height when using withGrid.
interface GridSizeContext {
containerWidth: number
columns: number
gap: number
columnWidth: number
}
| Property | Type | Description |
|---|---|---|
containerWidth |
number |
Current container width in pixels. |
columns |
number |
Number of grid columns. |
gap |
number |
Gap between items in pixels. |
columnWidth |
number |
Calculated column width in pixels. |
// Maintain 4:3 aspect ratio in grid
item: {
height: (index, ctx) => {
if (ctx) return ctx.columnWidth * 0.75
return 200 // fallback for non-grid
},
template: renderCard,
}
ItemTemplate #
Render function called for each visible item. Returns an HTML string or a DOM element.
type ItemTemplate<T = VListItem> = (
item: T,
index: number,
state: ItemState,
) => string | HTMLElement
| Parameter | Type | Description |
|---|---|---|
item |
T |
The data item for this row. |
index |
number |
The item's position in the full list. |
state |
ItemState |
Rendering state flags. |
ItemState #
State passed to templates. This object is reused between render calls — read values immediately, do not store the reference.
interface ItemState {
selected: boolean
focused: boolean
}
ScrollConfig #
Scroll behavior options, passed as the scroll property of BuilderConfig.
interface ScrollConfig {
wheel?: boolean
wrap?: boolean
gutter?: 'auto' | 'stable'
idleTimeout?: number
element?: Window
scrollbar?: 'native' | 'none' | ScrollbarOptions
}
| Property | Type | Default | Description |
|---|---|---|---|
wheel |
boolean |
true |
Whether mouse-wheel scrolling is enabled. |
wrap |
boolean |
false |
Circular scrolling — indices past the last item wrap to the beginning. |
idleTimeout |
number |
150 |
Milliseconds after the last scroll event before idle. Used by async loading and velocity tracking. |
element |
Window |
— | Use the browser window as the scroll container. |
scrollbar |
'native' | 'none' | ScrollbarOptions |
custom | Scrollbar mode. Omit for the default custom scrollbar. |
ScrollbarOptions #
Fine-tuning for the custom scrollbar. Pass as scroll.scrollbar or to withScrollbar().
interface ScrollbarOptions {
autoHide?: boolean
autoHideDelay?: number
minThumbSize?: number
showOnHover?: boolean
hoverZoneWidth?: number
showOnViewportEnter?: boolean
}
| Property | Type | Default | Description |
|---|---|---|---|
autoHide |
boolean |
true |
Hide the thumb after the list goes idle. |
autoHideDelay |
number |
1000 |
Milliseconds of idle time before the thumb fades out. |
minThumbSize |
number |
30 |
Minimum thumb size in pixels. |
showOnHover |
boolean |
true |
Reveal the scrollbar when the cursor moves near the scrollbar edge. |
hoverZoneWidth |
number |
16 |
Width of the invisible hover detection zone in pixels. |
showOnViewportEnter |
boolean |
true |
Show scrollbar when the cursor enters the list viewport. |
ScrollToOptions #
Options for scrollToIndex.
interface ScrollToOptions {
align?: 'start' | 'center' | 'end'
behavior?: 'auto' | 'smooth'
duration?: number
}
| Property | Type | Default | Description |
|---|---|---|---|
align |
'start' | 'center' | 'end' |
'start' |
Where to position the item in the viewport. |
behavior |
'auto' | 'smooth' |
'auto' |
Instant or animated scroll. |
duration |
number |
300 |
Animation duration in ms (smooth only). |
ScrollSnapshot #
Scroll position snapshot for save/restore. Used by withSnapshots.
interface ScrollSnapshot {
index: number
offsetInItem: number
total?: number
selectedIds?: Array<string | number>
}
| Property | Type | Description |
|---|---|---|
index |
number |
First visible item index. |
offsetInItem |
number |
Pixel offset within the first visible item. |
total |
number |
Total item count at snapshot time (used by restore to set sizeCache). |
selectedIds |
Array<string | number> |
Selected item IDs (optional convenience). |
ReloadOptions #
Options for the reload() method. Exported from vlist.
interface ReloadOptions {
skipInitialLoad?: boolean
snapshot?: ScrollSnapshot
}
| Property | Type | Description |
|---|---|---|
skipInitialLoad |
boolean |
Skip the initial page-1 load after resetting state. When true, reload() clears data and DOM but does not call loadInitial(). Automatically set when snapshot has meaningful data. |
snapshot |
ScrollSnapshot |
Snapshot to restore after reset. When provided with total > 0 and index > 0, reload() skips loadInitial() and calls restoreScroll(snapshot) automatically. |
Selection Types #
Selection state and configuration, used by withSelection().
SelectionConfig #
interface SelectionConfig {
mode?: SelectionMode
initial?: Array<string | number>
}
| Property | Type | Default | Description |
|---|---|---|---|
mode |
SelectionMode |
'none' |
Selection mode. |
initial |
Array<string | number> |
[] |
Initially selected item IDs. |
SelectionMode #
type SelectionMode = 'none' | 'single' | 'multiple'
SelectionState #
Internal selection state.
interface SelectionState {
selected: Set<string | number>
focusedIndex: number
}
Adapter Types #
Async data loading interfaces — define how vlist fetches, paginates, and receives remote data via withAsync().
VListAdapter #
interface VListAdapter<T extends VListItem = VListItem> {
read: (params: AdapterParams) => Promise<AdapterResponse<T>>
}
AdapterParams #
Parameters passed to adapter.read.
interface AdapterParams {
offset: number
limit: number
cursor: string | undefined
}
| Property | Type | Description |
|---|---|---|
offset |
number |
Starting offset. |
limit |
number |
Number of items to fetch. |
cursor |
string | undefined |
Cursor for cursor-based pagination. |
AdapterResponse #
Response from adapter.read.
interface AdapterResponse<T extends VListItem = VListItem> {
items: T[]
total?: number
cursor?: string
hasMore?: boolean
}
| Property | Type | Description |
|---|---|---|
items |
T[] |
Fetched items. |
total |
number |
Total count (if known). |
cursor |
string |
Next cursor for pagination. |
hasMore |
boolean |
Whether more items exist. |
State Types #
Runtime state exposed through events and the builder context — viewport geometry, scroll position, and visible ranges.
ViewportState #
The internal state of the virtual viewport. Updated on every scroll and resize.
interface ViewportState {
scrollPosition: number
containerSize: number
totalSize: number
actualSize: number
isCompressed: boolean
compressionRatio: number
visibleRange: Range
renderRange: Range
}
| Property | Type | Description |
|---|---|---|
scrollPosition |
number |
Current scroll offset along the main axis. |
containerSize |
number |
Container size along the main axis. |
totalSize |
number |
Total content size (may be capped for compression). |
actualSize |
number |
True total size without compression. |
isCompressed |
boolean |
Whether compression is active. |
compressionRatio |
number |
Ratio of virtual to actual size (1 = no compression). |
visibleRange |
Range |
Currently visible item range. |
renderRange |
Range |
Rendered range (includes overscan). |
Range #
A contiguous range of item indices.
interface Range {
start: number
end: number
}
Event Types #
Event names and their payloads. Subscribe with list.on(event, handler). See Events for detailed documentation of each event.
VListEvents #
interface VListEvents<T extends VListItem = VListItem> {
'item:click': { item: T; index: number; event: MouseEvent }
'item:dblclick': { item: T; index: number; event: MouseEvent }
'selection:change': { selected: Array<string | number>; items: T[] }
'scroll': { scrollPosition: number; direction: 'up' | 'down' }
'velocity:change': { velocity: number; reliable: boolean }
'range:change': { range: Range }
'load:start': { offset: number; limit: number }
'load:end': { items: T[]; total?: number; offset?: number }
'error': { error: Error; context: string; viewport?: ErrorViewportSnapshot }
'resize': { height: number; width: number }
'scroll:idle': { scrollPosition: number }
'destroy': undefined
}
EventHandler #
type EventHandler<T> = (payload: T) => void
Unsubscribe #
Returned by on(). Call it to remove the subscription.
type Unsubscribe = () => void
ErrorViewportSnapshot #
Viewport state snapshot attached to error events for debugging. Present on template and feature setup errors. Absent on destroy errors (viewport already torn down).
interface ErrorViewportSnapshot {
scrollPosition: number
containerSize: number
visibleRange: { start: number; end: number }
renderRange: { start: number; end: number }
totalItems: number
isCompressed: boolean
}
See Events — error for context strings and usage examples.
Feature Types #
Configuration interfaces for layout and behavior features — groups, grid, and masonry.
GroupsConfig #
Configuration for withGroups().
interface GroupsConfig {
getGroupForIndex: (index: number) => string
header?: {
height: number | ((group: string, groupIndex: number) => number)
width?: number | ((group: string, groupIndex: number) => number)
template: (group: string, groupIndex: number) => string | HTMLElement
}
sticky?: boolean
}
| Property | Type | Default | Description |
|---|---|---|---|
getGroupForIndex |
(index) => string |
— | Required. Returns the group key for a data index. Items must be pre-sorted by group. |
header.height |
number | (group, groupIndex) => number |
— | Size of group header elements in pixels (main axis). |
header.width |
number | (group, groupIndex) => number |
— | Size of group header elements in pixels (cross axis, for horizontal). |
header.template |
(group, groupIndex) => string | HTMLElement |
— | Render function for group headers. |
sticky |
boolean |
true |
Enable sticky headers that follow the viewport. |
Deprecated:
headerHeightandheaderTemplateas top-level properties still work but are deprecated. Use the nestedheaderobject instead.
GridConfig #
Configuration for withGrid().
interface GridConfig {
columns: number
gap?: number
}
| Property | Type | Default | Description |
|---|---|---|---|
columns |
number |
— | Required. Number of grid columns. |
gap |
number |
0 |
Gap between items in pixels (applied both horizontally and vertically). |
MasonryConfig #
Configuration for withMasonry().
interface MasonryConfig {
columns: number
gap?: number
}
| Property | Type | Default | Description |
|---|---|---|---|
columns |
number |
— | Required. Number of cross-axis divisions. Items flow into the shortest column. |
gap |
number |
0 |
Gap between items in pixels. |
Builder Types #
The builder pattern types — how features are registered and how the list is materialized.
VListBuilder #
The chainable builder returned by vlist().
interface VListBuilder<T extends VListItem = VListItem> {
use(feature: VListFeature<T>): VListBuilder<T>
build(): VList<T>
}
| Method | Description |
|---|---|
.use(feature) |
Register a feature. Chainable. |
.build() |
Materialize the list — creates DOM, initializes features, returns the instance API. |
VListFeature #
The interface for builder features. Each feature wires handlers and methods into the BuilderContext during setup.
interface VListFeature<T extends VListItem = VListItem> {
readonly name: string
readonly priority?: number
setup(ctx: BuilderContext<T>): void
destroy?(): void
readonly methods?: readonly string[]
readonly conflicts?: readonly string[]
}
| Property | Type | Default | Description |
|---|---|---|---|
name |
string |
— | Unique feature name (used for deduplication and error messages). |
priority |
number |
50 |
Execution order — lower runs first. |
setup |
(ctx) => void |
— | Receives BuilderContext, wires handlers and methods. |
destroy |
() => void |
— | Optional cleanup function called on list destroy. |
methods |
string[] |
— | Methods this feature adds to the public API. |
conflicts |
string[] |
— | Features this feature cannot be combined with. |
BuilderState #
Mutable state stored inside BuilderContext.
interface BuilderState {
viewportState: ViewportState
lastRenderRange: Range
isInitialized: boolean
isDestroyed: boolean
cachedCompression: CachedCompression | null
}
ResolvedBuilderConfig #
Immutable configuration stored inside BuilderContext after defaults are applied.
interface ResolvedBuilderConfig {
readonly overscan: number
readonly classPrefix: string
readonly reverse: boolean
readonly wrap: boolean
readonly horizontal: boolean
readonly ariaIdPrefix: string
}
For the full BuilderContext interface and feature authoring guide, see Exports — Feature Authoring.
Rendering Types #
Internal rendering infrastructure — size caches, DOM structure, compression, element pooling. Most users won't need these directly; they're documented for feature authors and advanced integrations.
SizeCache #
Efficient size management for fixed and variable item sizes. Axis-neutral — the same interface handles both vertical heights and horizontal widths.
interface SizeCache {
getOffset(index: number): number
getSize(index: number): number
indexAtOffset(offset: number): number
getTotalSize(): number
getTotal(): number
rebuild(totalItems: number): void
isVariable(): boolean
}
| Method | Description |
|---|---|
getOffset(index) |
Position of item along the main axis — O(1). |
getSize(index) |
Size of a specific item. |
indexAtOffset(offset) |
Item at a scroll offset — O(1) fixed, O(log n) variable. |
getTotalSize() |
Total content size. |
getTotal() |
Current item count. |
rebuild(total) |
Rebuild cache after data changes. |
isVariable() |
Whether sizes are variable (false = fixed fast path). |
DOMStructure #
The DOM hierarchy created by vlist.
interface DOMStructure {
root: HTMLElement
viewport: HTMLElement
content: HTMLElement
items: HTMLElement
}
CompressionContext #
Context for positioning items in compressed mode.
interface CompressionContext {
scrollPosition: number
totalItems: number
containerSize: number
rangeStart: number
}
CompressionState #
Result of compression calculation.
interface CompressionState {
isCompressed: boolean
actualSize: number
virtualSize: number
ratio: number
}
| Property | Type | Description |
|---|---|---|
isCompressed |
boolean |
Whether compression is active. |
actualSize |
number |
True total size (uncompressed). |
virtualSize |
number |
Capped size used for the scroll container (≤ MAX_VIRTUAL_SIZE). |
ratio |
number |
virtualSize / actualSize (1 = no compression, <1 = compressed). |
Renderer #
DOM rendering instance.
interface Renderer<T extends VListItem = VListItem> {
render: (items: T[], range: Range, selectedIds: Set<string | number>, focusedIndex: number, compressionCtx?: CompressionContext) => void
updatePositions: (compressionCtx: CompressionContext) => void
updateItem: (index: number, item: T, isSelected: boolean, isFocused: boolean) => void
updateItemClasses: (index: number, isSelected: boolean, isFocused: boolean) => void
getElement: (index: number) => HTMLElement | undefined
clear: () => void
destroy: () => void
}
ElementPool #
Element pool for recycling DOM elements.
interface ElementPool {
acquire: () => HTMLElement
release: (element: HTMLElement) => void
clear: () => void
stats: () => { poolSize: number; created: number; reused: number }
}
Emitter Types #
The type-safe event emitter used internally and available as a standalone export via createEmitter().
Emitter #
interface Emitter<T extends EventMap> {
on: <K extends keyof T>(event: K, handler: EventHandler<T[K]>) => Unsubscribe
off: <K extends keyof T>(event: K, handler: EventHandler<T[K]>) => void
emit: <K extends keyof T>(event: K, payload: T[K]) => void
clear: <K extends keyof T>(event?: K) => void
}
EventMap #
Base type for event maps.
type EventMap = Record<string, unknown>
Usage Examples #
Custom Item Type #
import { vlist } from 'vlist'
interface Product extends VListItem {
id: number
name: string
price: number
category: string
}
const list = vlist<Product>({
container: '#products',
item: {
height: 56,
template: (product, index, state) => `
<div class="product ${state.selected ? 'selected' : ''}">
<span>${product.name}</span>
<span>$${product.price.toFixed(2)}</span>
</div>
`,
},
items: products,
}).build()
Typed Event Handlers #
interface User extends VListItem {
id: string
name: string
email: string
}
list.on('item:click', ({ item, index, event }) => {
// item is typed as User
console.log(item.name, item.email)
})
list.on('selection:change', ({ selected, items }) => {
// items is typed as User[]
console.log(`${selected.length} users selected`)
})
Adapter Type Safety #
interface Article extends VListItem {
id: number
title: string
body: string
publishedAt: string
}
const adapter: VListAdapter<Article> = {
read: async ({ offset, limit }) => {
const response = await fetch(`/api/articles?offset=${offset}&limit=${limit}`)
const data = await response.json()
return {
items: data.articles,
total: data.total,
hasMore: data.hasMore,
}
},
}
Summary #
| Category | Types | Purpose |
|---|---|---|
| Public API | VList |
Instance methods, properties, and events |
| Item | VListItem |
Base item constraint |
| Configuration | BuilderConfig, VListConfig, ItemConfig, GridSizeContext, ItemTemplate, ItemState, ScrollConfig, ScrollbarOptions, ScrollToOptions, ScrollSnapshot |
All config interfaces from top-level down to scroll options |
| Selection | SelectionConfig, SelectionMode, SelectionState |
Selection mode and state |
| Adapter | VListAdapter, AdapterParams, AdapterResponse |
Async data loading |
| State | ViewportState, Range |
Runtime viewport geometry |
| Events | VListEvents, EventHandler, Unsubscribe |
Event names, payloads, and subscription |
| Features | GroupsConfig, GridConfig, MasonryConfig |
Feature configuration |
| Builder | VListBuilder, VListFeature, BuilderState, ResolvedBuilderConfig |
Builder pattern and feature interface |
| Rendering | SizeCache, DOMStructure, CompressionContext, CompressionState, Renderer, ElementPool |
Internal rendering infrastructure |
| Emitter | Emitter, EventMap |
Type-safe event emitter |
Related #
- API Reference — Config, properties, and methods
- Events — All events and payloads
- Constants — Default values and thresholds
- Exports — Low-level utilities,
BuilderContext, and feature authoring - Features — All features with examples and compatibility
All types are exported from vlist — import what you need.