From a0afaf0369159e9cfbcbd366889b06d8f4daa13b Mon Sep 17 00:00:00 2001 From: J-Sek Date: Fri, 21 Nov 2025 15:12:04 +0100 Subject: [PATCH] feat(VDataIterator): add `items-length` prop resolves #19486 --- .../VDataIterator/VDataIterator.tsx | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/packages/vuetify/src/components/VDataIterator/VDataIterator.tsx b/packages/vuetify/src/components/VDataIterator/VDataIterator.tsx index 34e3064b5a8..dfdfb5ff60a 100644 --- a/packages/vuetify/src/components/VDataIterator/VDataIterator.tsx +++ b/packages/vuetify/src/components/VDataIterator/VDataIterator.tsx @@ -19,11 +19,12 @@ import { makeFilterProps, useFilter } from '@/composables/filter' import { LoaderSlot } from '@/composables/loader' import { useProxiedModel } from '@/composables/proxiedModel' import { makeTagProps } from '@/composables/tag' +import { useToggleScope } from '@/composables/toggleScope' import { makeTransitionProps, MaybeTransition } from '@/composables/transition' // Utilities -import { computed, toRef } from 'vue' -import { genericComponent, propsFactory, useRender } from '@/util' +import { computed, shallowRef, toRef, watchEffect } from 'vue' +import { genericComponent, isEmpty, propsFactory, useRender } from '@/util' // Types import type { Component } from 'vue' @@ -67,6 +68,7 @@ export type VDataIteratorSlots = { export const makeVDataIteratorProps = propsFactory({ search: String, loading: Boolean, + itemsLength: [Number, String], ...makeComponentProps(), ...makeDataIteratorItemsProps(), @@ -122,7 +124,8 @@ export const VDataIterator = genericComponent ( const { sortedItems } = useSortedItems(props, filteredItems, sortByWithGroups, { transform: item => item.raw }) const { flatItems } = useGroupedItems(sortedItems, groupBy, opened, false) - const itemsLength = toRef(() => flatItems.value.length) + const manualPagination = toRef(() => !isEmpty(props.itemsLength)) + const itemsLength = toRef(() => manualPagination.value ? Number(props.itemsLength) : flatItems.value.length) const { startIndex, @@ -133,16 +136,26 @@ export const VDataIterator = genericComponent ( setItemsPerPage, setPage, } = providePagination({ page, itemsPerPage, itemsLength }) - const { paginatedItems } = usePaginatedItems({ items: flatItems, startIndex, stopIndex, itemsPerPage }) - const paginatedItemsWithoutGroups = computed(() => extractRows(paginatedItems.value)) + const paginatedItems = shallowRef([]) + const currentItems = computed(() => manualPagination.value ? flatItems.value : paginatedItems.value) + + useToggleScope(() => !manualPagination.value, () => { + const { paginatedItems: items } = usePaginatedItems({ items: flatItems, startIndex, stopIndex, itemsPerPage }) + + watchEffect(() => { + paginatedItems.value = items.value + }) + }) + + const currentItemsWithoutGroups = computed(() => extractRows(currentItems.value)) const { isSelected, select, selectAll, toggleSelect, - } = provideSelection(props, { allItems: items, currentPage: paginatedItemsWithoutGroups }) + } = provideSelection(props, { allItems: items, currentPage: currentItemsWithoutGroups }) const { isExpanded, toggleExpand } = provideExpanded(props) useOptions({ @@ -171,9 +184,9 @@ export const VDataIterator = genericComponent ( toggleExpand, isGroupOpen, toggleGroup, - items: paginatedItemsWithoutGroups.value, + items: currentItemsWithoutGroups.value, itemsCount: filteredItems.value.length, - groupedItems: paginatedItems.value, + groupedItems: currentItems.value, })) useRender(() => ( @@ -196,7 +209,7 @@ export const VDataIterator = genericComponent ( ) : (
- { !paginatedItems.value.length + { !currentItems.value.length ? slots['no-data']?.() : slots.default?.(slotProps.value) }