diff --git a/docs/content/docs/2.components/table.md b/docs/content/docs/2.components/table.md index 02f361002e..d31fca4615 100644 --- a/docs/content/docs/2.components/table.md +++ b/docs/content/docs/2.components/table.md @@ -686,6 +686,24 @@ class: '!p-0' A height constraint is required on the table for virtualization to work properly (e.g., `class="h-[400px]"`). :: +### Dynamic row heights :badge{label="Soon" class="align-text-top"} + +`estimateSize` is only the initial guess — the virtualizer measures every rendered row and updates its internal size map as you scroll. For rows with variable content (expandable rows, rich text, images), pass a `measureElement` callback to read the actual rendered height: + +```vue + +``` + +When a row is expanded via `row.toggleExpanded()`, the expansion row's height is automatically added to the measurement — you don't need to walk siblings yourself. + ### With tree data You can use the `get-sub-rows` prop to display hierarchical (tree) data in the table. diff --git a/src/runtime/components/Table.vue b/src/runtime/components/Table.vue index 5e508c02aa..8931334771 100644 --- a/src/runtime/components/Table.vue +++ b/src/runtime/components/Table.vue @@ -99,6 +99,21 @@ export interface TableProps extends TableOption meta?: TableMeta /** * Enable virtualization for large datasets. + * + * Pass a `measureElement` function to opt into dynamic row heights. The value returned by + * your `measureElement` is used as the height of the main row; when `row.getIsExpanded()` + * is `true`, the immediate next-sibling ``'s height is **added on top of** that value + * automatically, so your callback should measure the main row only. If your custom + * `measureElement` already includes the expanded region (e.g. by measuring a wrapper), + * return only the collapsed-row height to avoid double-counting. + * + * TanStack Virtual's `ResizeObserver` is attached to the main `` only, and this + * component re-measures rows whenever the TanStack expanded state toggles. It does **not** + * observe size changes *inside* the expansion sibling — late-loading images, async content, + * or nested toggles that resize the expansion region after mount won't trigger an automatic + * re-measure. Call `virtualizer.measure()` (or `virtualizer.measureElement(row)`) yourself + * in those cases. + * * Note: row pinning is not supported when virtualization is enabled. * @see https://tanstack.com/virtual/latest/docs/api/virtualizer#options * @defaultValue false @@ -110,7 +125,8 @@ export interface TableProps extends TableOption */ overscan?: number /** - * Estimated size (in px) of each item, or a function that returns the size for a given index + * Estimated size (in px) of each item, or a function that returns the size for a given index. + * Used as the initial estimate before the virtualizer measures actual row heights. * @defaultValue 65 */ estimateSize?: number | ((index: number) => number) @@ -224,7 +240,7 @@ export type TableSlots = {