Skip to content

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.

ID
Name
Price
Category
1
Product 1
$630.03
Electronics
2
Product 2
$607.80
Clothing
3
Product 3
$58.82
Accessories
4
Product 4
$861.30
Electronics
5
Product 5
$189.44
Clothing
6
Product 6
$926.01
Accessories
7
Product 7
$99.01
Electronics
8
Product 8
$981.78
Clothing
9
Product 9
$872.29
Accessories
10
Product 10
$353.08
Electronics
11
Product 11
$709.70
Clothing
12
Product 12
$676.40
Accessories
13
Product 13
$342.97
Electronics
14
Product 14
$166.43
Clothing

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.

ID
Name
Price
Category
Stock
Supplier
1
Product 1
$604.88
Electronics
67
Supplier A
2
Product 2
$842.71
Clothing
902
Supplier B
3
Product 3
$89.93
Accessories
2
Supplier C
4
Product 4
$901.49
Electronics
61
Supplier A
5
Product 5
$783.41
Clothing
351
Supplier B
6
Product 6
$269.59
Accessories
759
Supplier C
7
Product 7
$872.92
Electronics
983
Supplier A
8
Product 8
$990.56
Clothing
85
Supplier B
9
Product 9
$219.89
Accessories
572
Supplier C
10
Product 10
$298.67
Electronics
385
Supplier A
11
Product 11
$611.28
Clothing
494
Supplier B
12
Product 12
$511.72
Accessories
389
Supplier C
13
Product 13
$909.46
Electronics
161
Supplier A
14
Product 14
$500.01
Clothing
92
Supplier B

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.

ID
Name
Price
Category
1
Product 1
$630.03
Electronics
2
Product 2
$607.80
Clothing
3
Product 3
$58.82
Accessories
4
Product 4
$861.30
Electronics
5
Product 5
$189.44
Clothing
6
Product 6
$926.01
Accessories
7
Product 7
$99.01
Electronics
8
Product 8
$981.78
Clothing
9
Product 9
$872.29
Accessories
10
Product 10
$353.08
Electronics
11
Product 11
$709.70
Clothing
12
Product 12
$676.40
Accessories
13
Product 13
$342.97
Electronics
14
Product 14
$166.43
Clothing

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.

ID
Name
Price
Category
In Stock
1
Product 1
$66.99
Electronics
false
2
Product 2
$28.32
Clothing
true
3
Product 3
$217.22
Accessories
true
4
Product 4
$88.09
Home
false
5
Product 5
$104.86
Sports
true
6
Product 6
$871.35
Electronics
true
7
Product 7
$73.31
Clothing
false
8
Product 8
$479.63
Accessories
true
9
Product 9
$10.76
Home
true
10
Product 10
$91.85
Sports
false
11
Product 11
$935.32
Electronics
true
12
Product 12
$476.16
Clothing
true
13
Product 13
$884.95
Accessories
false
14
Product 14
$980.98
Home
true

Basic Usage

vue
<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:

vue
<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:

vue
<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:

vue
<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.

ID
Name
Description
Status
Priority
1
Item 1
Description for item 1
Active
High
2
Item 2
Description for item 2
Inactive
Medium
3
Item 3
Description for item 3
Pending
Low
4
Item 4
Description for item 4
Active
High
5
Item 5
Description for item 5
Inactive
Medium
6
Item 6
Description for item 6
Pending
Low
7
Item 7
Description for item 7
Active
High
8
Item 8
Description for item 8
Inactive
Medium
9
Item 9
Description for item 9
Pending
Low
10
Item 10
Description for item 10
Active
High
11
Item 11
Description for item 11
Inactive
Medium
12
Item 12
Description for item 12
Pending
Low
13
Item 13
Description for item 13
Active
High
14
Item 14
Description for item 14
Inactive
Medium
15
Item 15
Description for item 15
Pending
Low
16
Item 16
Description for item 16
Active
High
17
Item 17
Description for item 17
Inactive
Medium
18
Item 18
Description for item 18
Pending
Low
19
Item 19
Description for item 19
Active
High
20
Item 20
Description for item 20
Inactive
Medium

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.

ID
Name
Price
Category
In Stock
Rating
1
Product 1
$270.55
Electronics
false
2.8
2
Product 2
$208.94
Clothing
true
1.6
3
Product 3
$797.70
Accessories
true
2
4
Product 4
$603.25
Home
false
3.5
5
Product 5
$113.11
Sports
true
1.2
6
Product 6
$93.01
Electronics
true
1.4
7
Product 7
$19.50
Clothing
false
1.2
8
Product 8
$740.69
Accessories
true
4.7
9
Product 9
$642.17
Home
true
2.2
10
Product 10
$224.92
Sports
false
1.5
11
Product 11
$654.52
Electronics
true
2
12
Product 12
$541.00
Clothing
true
2.7
13
Product 13
$158.48
Accessories
false
3.3
14
Product 14
$894.33
Home
true
3.8
15
Product 15
$297.33
Sports
true
4
16
Product 16
$314.72
Electronics
false
4
17
Product 17
$485.46
Clothing
true
3.2
18
Product 18
$813.90
Accessories
true
2.7
19
Product 19
$451.28
Home
false
2.7
20
Product 20
$947.35
Sports
true
4.9
21
Product 21
$194.83
Electronics
true
2.4
22
Product 22
$320.71
Clothing
false
3.3
23
Product 23
$939.58
Accessories
true
4.1
24
Product 24
$853.49
Home
true
4.8
25
Product 25
$982.36
Sports
false
3
26
Product 26
$196.05
Electronics
true
1
27
Product 27
$884.00
Clothing
true
5
28
Product 28
$771.80
Accessories
false
2.3
29
Product 29
$180.02
Home
true
4.5
30
Product 30
$726.03
Sports
true
2.6

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.

ID
Name
Description
Status
Priority
1
Item 1
Description for item 1
Active
High
2
Item 2
Description for item 2
Inactive
Medium
3
Item 3
Description for item 3
Pending
Low
4
Item 4
Description for item 4
Active
High
5
Item 5
Description for item 5
Inactive
Medium
6
Item 6
Description for item 6
Pending
Low
7
Item 7
Description for item 7
Active
High
8
Item 8
Description for item 8
Inactive
Medium
9
Item 9
Description for item 9
Pending
Low
10
Item 10
Description for item 10
Active
High
11
Item 11
Description for item 11
Inactive
Medium
12
Item 12
Description for item 12
Pending
Low
13
Item 13
Description for item 13
Active
High
14
Item 14
Description for item 14
Inactive
Medium
15
Item 15
Description for item 15
Pending
Low
16
Item 16
Description for item 16
Active
High
17
Item 17
Description for item 17
Inactive
Medium
18
Item 18
Description for item 18
Pending
Low
19
Item 19
Description for item 19
Active
High
20
Item 20
Description for item 20
Inactive
Medium
21
Item 21
Description for item 21
Pending
Low
22
Item 22
Description for item 22
Active
High
23
Item 23
Description for item 23
Inactive
Medium
24
Item 24
Description for item 24
Pending
Low
25
Item 25
Description for item 25
Active
High

Endless scrolling with 5,000 rows using scrollable-endless prop. Scroll to the bottom to automatically load more items. No pagination controls needed.

ID
Name
Description
Status
Priority
1
Item 1
Description for item 1
Active
High
2
Item 2
Description for item 2
Inactive
Medium
3
Item 3
Description for item 3
Pending
Low
4
Item 4
Description for item 4
Active
High
5
Item 5
Description for item 5
Inactive
Medium
6
Item 6
Description for item 6
Pending
Low
7
Item 7
Description for item 7
Active
High
8
Item 8
Description for item 8
Inactive
Medium
9
Item 9
Description for item 9
Pending
Low
10
Item 10
Description for item 10
Active
High
11
Item 11
Description for item 11
Inactive
Medium
12
Item 12
Description for item 12
Pending
Low
13
Item 13
Description for item 13
Active
High
14
Item 14
Description for item 14
Inactive
Medium
15
Item 15
Description for item 15
Pending
Low
16
Item 16
Description for item 16
Active
High
17
Item 17
Description for item 17
Inactive
Medium
18
Item 18
Description for item 18
Pending
Low
19
Item 19
Description for item 19
Active
High
20
Item 20
Description for item 20
Inactive
Medium

Basic Usage

vue
<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:

vue
<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:

vue
<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

vue
<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

Featurescrollable-virtualscrollable-endless
RenderingOnly visible rowsAll loaded rows
MemoryLow (constant)Medium (grows)
PerformanceExcellentGood
Use CaseVery large datasets (10k+)Medium datasets (1k-10k)
LoadingInstantProgressive
ScrollbarFull heightGrows 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

vue
<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

vue
<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

vue
<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

vue
<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

vue
<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

  1. Set fixed row height: Improves scroll position calculations
  2. Limit column count: Fewer columns = faster rendering
  3. Avoid complex templates: Simple cell templates perform better
  4. Use column widths: Fixed widths prevent layout recalculations

For Endless Scrolling

  1. Optimize page size: Balance between initial load and scroll frequency
  2. Use appropriate thresholds: Default 100px from bottom works well
  3. Consider data structure: Flat data structures load faster
  4. Monitor memory: Watch for memory growth with very large datasets

Configuration Options

Virtual Scrolling Configuration

vue
<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

vue
<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 height prop
  • Works best with fixed rowHeight
  • Not compatible with standard pagination
  • May have issues with variable row heights

scrollable-endless

  • Requires fixed height prop
  • Memory usage grows with loaded items
  • Not recommended for datasets > 10,000 rows
  • Not compatible with server-side mode

See Also