Scrollable Props
Pantanal Grid provides advanced scrolling capabilities through scrollable-virtual and scrollable-endless props, enabling efficient handling of large datasets.
Small Dataset (1,000 rows)
Virtual scrolling with 1,000 rows using scrollable-virtual prop. Only visible rows are rendered for optimal performance.
Large Dataset (10,000 rows)
Virtual scrolling with 10,000 rows. Even with a large dataset, performance remains smooth. Try sorting and filtering to see how virtual scrolling handles operations efficiently.
Virtual Scrolling with Sorting and Filtering
Virtual scrolling works seamlessly with sorting and filtering. Operations are performed on the full dataset, but only visible rows are rendered.
scrollable-virtual
The scrollable-virtual prop enables virtual scrolling, rendering only visible rows for optimal performance with large datasets.
Virtual scrolling with 10,000 rows using scrollable-virtual prop. Only visible rows are rendered for optimal performance. Scroll through the data to see smooth performance.
Basic Usage
<script setup lang="ts">
import { ref } from 'vue'
import { PantanalGrid, type ColumnDef } from '@pantanal/grid'
const rows = ref(Array.from({ length: 10000 }, (_, i) => ({
id: i + 1,
name: `Product ${i + 1}`,
price: Math.round(Math.random() * 100000) / 100,
category: ['Electronics', 'Clothing', 'Accessories'][i % 3]
})))
const columns: ColumnDef[] = [
{ field: 'id', title: 'ID', width: 80, sortable: true },
{ field: 'name', title: 'Name', sortable: true, filterable: true },
{ field: 'price', title: 'Price', sortable: true, format: (v: number) => `$${v.toFixed(2)}` },
{ field: 'category', title: 'Category', filterable: true }
]
</script>
<template>
<PantanalGrid
:rows="rows"
:columns="columns"
key-field="id"
scrollable-virtual
:height="420"
:row-height="44"
/>
</template>With Sorting and Filtering
Virtual scrolling works seamlessly with sorting and filtering:
<template>
<PantanalGrid
:rows="rows"
:columns="columns"
key-field="id"
scrollable-virtual
:height="420"
:row-height="44"
sortable
filterable
show-filter-row
/>
</template>Using scrollable Object
You can also use the scrollable prop as an object:
<template>
<PantanalGrid
:rows="rows"
:columns="columns"
key-field="id"
:scrollable="{ virtual: true }"
:height="420"
:row-height="44"
/>
</template>Custom Height and Row Height
Adjust the viewport and row dimensions:
<template>
<PantanalGrid
:rows="rows"
:columns="columns"
key-field="id"
scrollable-virtual
:height="600"
:row-height="50"
/>
</template>scrollable-endless
The scrollable-endless prop enables infinite scrolling, progressively loading more items as you scroll to the bottom.
Medium Dataset (2,000 rows)
Endless scrolling with 2,000 rows using scrollable-endless prop. Scroll to the bottom to automatically load more items. No pagination controls needed.
Large Dataset (5,000 rows)
Endless scrolling with 5,000 rows. Scroll down to see items load progressively. Try sorting and filtering to see how endless scrolling works with operations.
Endless Scrolling with Sorting and Filtering
Endless scrolling works seamlessly with sorting and filtering. As you scroll, more items are loaded automatically based on the current filter and sort state.
Endless scrolling with 5,000 rows using scrollable-endless prop. Scroll to the bottom to automatically load more items. No pagination controls needed.
Basic Usage
<script setup lang="ts">
import { ref } from 'vue'
import { PantanalGrid, type ColumnDef } from '@pantanal/grid'
const rows = ref(Array.from({ length: 5000 }, (_, i) => ({
id: i + 1,
name: `Item ${i + 1}`,
description: `Description for item ${i + 1}`,
status: ['Active', 'Inactive', 'Pending'][i % 3]
})))
const columns: ColumnDef[] = [
{ field: 'id', title: 'ID', width: 80 },
{ field: 'name', title: 'Name' },
{ field: 'description', title: 'Description' },
{ field: 'status', title: 'Status' }
]
</script>
<template>
<PantanalGrid
:rows="rows"
:columns="columns"
key-field="id"
scrollable-endless
:height="420"
:row-height="44"
:page-size="20"
/>
</template>Custom Page Size
Control how many items load initially and incrementally:
<template>
<PantanalGrid
:rows="rows"
:columns="columns"
key-field="id"
scrollable-endless
:height="420"
:row-height="44"
:page-size="50"
/>
</template>With Sorting and Filtering
Endless scrolling works with sorting and filtering:
<template>
<PantanalGrid
:rows="rows"
:columns="columns"
key-field="id"
scrollable-endless
:height="420"
:row-height="44"
:page-size="20"
sortable
filterable
show-filter-row
/>
</template>Using scrollable Object
<template>
<PantanalGrid
:rows="rows"
:columns="columns"
key-field="id"
:scrollable="{ endless: true }"
:height="420"
:row-height="44"
:page-size="20"
/>
</template>Comparison
scrollable-virtual vs scrollable-endless
| Feature | scrollable-virtual | scrollable-endless |
|---|---|---|
| Rendering | Only visible rows | All loaded rows |
| Memory | Low (constant) | Medium (grows) |
| Performance | Excellent | Good |
| Use Case | Very large datasets (10k+) | Medium datasets (1k-10k) |
| Loading | Instant | Progressive |
| Scrollbar | Full height | Grows as loaded |
When to Use Each
Use scrollable-virtual when:
- ✅ Dataset has 10,000+ rows
- ✅ Memory usage is a concern
- ✅ You need maximum performance
- ✅ Fixed viewport height is acceptable
Use scrollable-endless when:
- ✅ Dataset has 1,000-10,000 rows
- ✅ You want infinite scroll UX
- ✅ Progressive loading is acceptable
- ✅ You want to avoid pagination controls
Use standard pagination when:
- ✅ Dataset has < 1,000 rows
- ✅ Users need explicit page navigation
- ✅ You want predictable page-based navigation
Advanced Examples
Virtual Scrolling with Grouping
<script setup lang="ts">
import { ref } from 'vue'
import { PantanalGrid, type ColumnDef, type GroupDescriptor } from '@pantanal/grid'
const rows = ref(Array.from({ length: 5000 }, (_, i) => ({
id: i + 1,
name: `Product ${i + 1}`,
category: ['Electronics', 'Clothing', 'Accessories'][i % 3],
price: Math.round(Math.random() * 100000) / 100
})))
const columns: ColumnDef[] = [
{ field: 'id', title: 'ID', width: 80 },
{ field: 'name', title: 'Name' },
{ field: 'category', title: 'Category' },
{ field: 'price', title: 'Price', format: (v: number) => `$${v.toFixed(2)}` }
]
const group = ref<GroupDescriptor[]>([{ field: 'category' }])
</script>
<template>
<PantanalGrid
:rows="rows"
:columns="columns"
key-field="id"
scrollable-virtual
:height="420"
:row-height="44"
v-model:group="group"
/>
</template>Endless Scrolling with Custom Templates
<script setup lang="ts">
import { ref } from 'vue'
import { PantanalGrid, type ColumnDef } from '@pantanal/grid'
const rows = ref(Array.from({ length: 3000 }, (_, i) => ({
id: i + 1,
name: `Item ${i + 1}`,
status: ['Active', 'Inactive'][i % 2],
priority: i % 5
})))
const columns: ColumnDef[] = [
{ field: 'id', title: 'ID', width: 80 },
{
field: 'name',
title: 'Name',
template: ({ value }) => `<strong>${value}</strong>`
},
{
field: 'status',
title: 'Status',
template: ({ value }) =>
`<span style="color: ${value === 'Active' ? 'green' : 'red'}">${value}</span>`
},
{ field: 'priority', title: 'Priority' }
]
</script>
<template>
<PantanalGrid
:rows="rows"
:columns="columns"
key-field="id"
scrollable-endless
:height="420"
:row-height="44"
:page-size="25"
/>
</template>Virtual Scrolling with Selection
<script setup lang="ts">
import { ref } from 'vue'
import { PantanalGrid, type ColumnDef } from '@pantanal/grid'
const rows = ref(Array.from({ length: 8000 }, (_, i) => ({
id: i + 1,
name: `Product ${i + 1}`,
price: Math.round(Math.random() * 100000) / 100
})))
const columns: ColumnDef[] = [
{ field: 'id', title: 'ID', width: 80 },
{ field: 'name', title: 'Name' },
{ field: 'price', title: 'Price', format: (v: number) => `$${v.toFixed(2)}` }
]
const selectedKeys = ref<number[]>([])
</script>
<template>
<div>
<p>Selected: {{ selectedKeys.length }} items</p>
<PantanalGrid
:rows="rows"
:columns="columns"
key-field="id"
scrollable-virtual
:height="420"
:row-height="44"
selectable="multiple"
v-model:selectedKeys="selectedKeys"
/>
</div>
</template>Endless Scrolling with Striped Rows
<template>
<PantanalGrid
:rows="rows"
:columns="columns"
key-field="id"
scrollable-endless
:height="420"
:row-height="44"
:page-size="20"
striped
/>
</template>Virtual Scrolling with Pinned Columns
<script setup lang="ts">
const columns: ColumnDef[] = [
{ field: 'id', title: 'ID', width: 80, pinned: 'left' },
{ field: 'name', title: 'Name', width: 200 },
{ field: 'description', title: 'Description', width: 300 },
{ field: 'price', title: 'Price', width: 120, pinned: 'right' }
]
</script>
<template>
<PantanalGrid
:rows="rows"
:columns="columns"
key-field="id"
scrollable-virtual
:height="420"
:row-height="44"
/>
</template>Performance Tips
For Virtual Scrolling
- Set fixed row height: Improves scroll position calculations
- Limit column count: Fewer columns = faster rendering
- Avoid complex templates: Simple cell templates perform better
- Use column widths: Fixed widths prevent layout recalculations
For Endless Scrolling
- Optimize page size: Balance between initial load and scroll frequency
- Use appropriate thresholds: Default 100px from bottom works well
- Consider data structure: Flat data structures load faster
- Monitor memory: Watch for memory growth with very large datasets
Configuration Options
Virtual Scrolling Configuration
<template>
<PantanalGrid
:rows="rows"
:columns="columns"
key-field="id"
scrollable-virtual
:height="500" <!-- Viewport height -->
:row-height="50" <!-- Fixed row height -->
/>
</template>Endless Scrolling Configuration
<template>
<PantanalGrid
:rows="rows"
:columns="columns"
key-field="id"
scrollable-endless
:height="500" <!-- Viewport height -->
:row-height="50" <!-- Row height -->
:page-size="30" <!-- Initial and incremental load size -->
/>
</template>Limitations
scrollable-virtual
- Requires fixed
heightprop - Works best with fixed
rowHeight - Not compatible with standard pagination
- May have issues with variable row heights
scrollable-endless
- Requires fixed
heightprop - Memory usage grows with loaded items
- Not recommended for datasets > 10,000 rows
- Not compatible with server-side mode
See Also
- Virtual Scrolling Guide - Complete virtual scrolling documentation
- ScrollableProps API - API reference
- Grid Props API - All grid props