@ -1,16 +1,18 @@
< template >
< template >
< div class = "list-table-v2" :style ="containerStyle" >
< div class = "list-table-v2" :style ="containerStyle" >
<!-- Mini hidden table for measuring row height ( only when using dynamic height mode ) -- >
<!-- Mini hidden table for measuring row height and header height ( only when using dynamic height mode ) -- >
<!-- This mirrors the real table ' s cell rendering for accurate height estimation -- >
<!-- This mirrors the real table ' s cell rendering for accurate height estimation -- >
< div v-if ="shouldUseProbeRow" ref="miniTableRef" class="mini-table" aria-hidden="true" >
< div v-if ="shouldUseProbeRow" ref="miniTableRef" class="mini-table" aria-hidden="true" >
< div v-if ="miniTableData.length > 0" class="mini-table-inner" >
< div v-if ="miniTableData.length > 0" class="mini-table-inner" >
<!-- Mini header row -- >
< div ref = "miniHeaderRef" class = "mini-row mini-header" >
< div v-for ="item in prop.columns || []" :key="item.key" class="mini-cell mini-header-cell" :style="getMiniCellStyle(item)" >
< span class = "mini-header-content" > { item . name || ( item . i18n ? t ( item . i18n ) : item . key ) } < / span >
< / div >
< / div >
<!-- Mini data rows -- >
< div v-for ="(row, rowIdx) in miniTableData" :key="rowIdx" class="mini-row" >
< div v-for ="(row, rowIdx) in miniTableData" :key="rowIdx" class="mini-row" >
< div
< div v-for ="item in prop.columns || []" :key="item.key" class="mini-cell" :style="getMiniCellStyle(item)" >
v - for = "item in prop.columns || []"
: key = "item.key"
class = "mini-cell"
: style = "getMiniCellStyle(item)"
>
{ renderCellContent ( item , lodash . get ( row , item . dataKey || item . key ) , row , slots ) }
{ renderCellContent ( item , lodash . get ( row , item . dataKey || item . key ) , row , slots ) }
< / div >
< / div >
< / div >
< / div >
@ -27,7 +29,7 @@
: width = "width"
: width = "width"
: height = "resolvedHeight(height)"
: height = "resolvedHeight(height)"
: row - height = "prop.rowHeight"
: row - height = "prop.rowHeight"
: header - height = "prop.h eaderHeight"
: header - height = "resolvedH eaderHeight"
: estimated - row - height = "estimatedRowHeightToUse"
: estimated - row - height = "estimatedRowHeightToUse"
: border = "border"
: border = "border"
: row - key = "rowKey"
: row - key = "rowKey"
@ -68,9 +70,11 @@ const { t } = useI18n();
const { state } = useStore ( ) ;
const { state } = useStore ( ) ;
const table = ref ( ) ;
const table = ref ( ) ;
const miniTableRef = ref ( ) ;
const miniTableRef = ref ( ) ;
const miniHeaderRef = ref ( ) ;
const myTableRef = ref ( ) ; / / R e f e r e n c e t o . m y - t a b l e f o r R e s i z e O b s e r v e r
const myTableRef = ref ( ) ; / / R e f e r e n c e t o . m y - t a b l e f o r R e s i z e O b s e r v e r
const miniTableData = ref < any [ ] > ( [ ] ) ;
const miniTableData = ref < any [ ] > ( [ ] ) ;
const estimatedRowHeight = ref < number | undefined > ( undefined ) ;
const estimatedRowHeight = ref < number | undefined > ( undefined ) ;
const estimatedHeaderHeight = ref < number | undefined > ( undefined ) ;
let miniTableResizeObserver : ResizeObserver | null = null ;
let miniTableResizeObserver : ResizeObserver | null = null ;
/ / H e a d e r h e i g h t c o n s t a n t
/ / H e a d e r h e i g h t c o n s t a n t
@ -198,7 +202,14 @@ const estimatedRowHeightToUse = computed(() => {
return estimatedRowHeight . value ; / / u s e p r o b e - m e a s u r e d v a l u e
return estimatedRowHeight . value ; / / u s e p r o b e - m e a s u r e d v a l u e
} ) ;
} ) ;
/ / M e a s u r e m i n i t a b l e r o w h e i g h t w h e n d a t a c h a n g e s ( o n l y w h e n u s i n g p r o b e r o w )
/ / T h e h e a d e r h e i g h t t o p a s s t o e l - t a b l e - v 2
/ / O n l y u s e m e a s u r e d h e a d e r h e i g h t w h e n p r o p . h e a d e r H e i g h t i s N O T e x p l i c i t l y s e t
const resolvedHeaderHeight = computed ( ( ) => {
if ( prop . headerHeight !== undefined ) return prop . headerHeight ; / / u s e r p r o v i d e d , u s e i t
return estimatedHeaderHeight . value ; / / u s e m i n i - t a b l e m e a s u r e d h e a d e r h e i g h t
} ) ;
/ / M e a s u r e m i n i t a b l e r o w a n d h e a d e r h e i g h t s w h e n d a t a c h a n g e s ( o n l y w h e n u s i n g p r o b e r o w )
/ / W e u s e T W O f r a m e s d e l a y t o l e t e l - t a b l e - v 2 f u l l y s e t t l e b e f o r e m e a s u r i n g
/ / W e u s e T W O f r a m e s d e l a y t o l e t e l - t a b l e - v 2 f u l l y s e t t l e b e f o r e m e a s u r i n g
watch (
watch (
( ) => pageData . value ,
( ) => pageData . value ,
@ -214,11 +225,17 @@ watch(
/ / W a i t T W O f r a m e s f o r l a y o u t t o s e t t l e
/ / W a i t T W O f r a m e s f o r l a y o u t t o s e t t l e
await new Promise ( ( resolve ) => requestAnimationFrame ( resolve ) ) ;
await new Promise ( ( resolve ) => requestAnimationFrame ( resolve ) ) ;
await new Promise ( ( resolve ) => requestAnimationFrame ( resolve ) ) ;
await new Promise ( ( resolve ) => requestAnimationFrame ( resolve ) ) ;
/ / M e a s u r e h e a d e r h e i g h t
const headerEl = miniTableRef . value ? . querySelector ( ".mini-header" ) ;
const headerHeight = headerEl ? . offsetHeight ;
if ( headerHeight && headerHeight > 0 ) {
estimatedHeaderHeight . value = headerHeight ;
}
/ / M e a s u r e f i r s t r o w h e i g h t
/ / M e a s u r e f i r s t r o w h e i g h t
const firstRow = miniTableRef . value ? . querySelector ( ".mini-row" ) ;
const firstRow = miniTableRef . value ? . querySelector ( ".mini-row:not(.mini-header) " ) ;
const height = firstRow ? . offsetHeight ;
const rowH eight = firstRow ? . offsetHeight ;
if ( height && height > 0 ) {
if ( rowHeight && rowH eight > 0 ) {
estimatedRowHeight . value = height ;
estimatedRowHeight . value = rowH eight;
}
}
} ,
} ,
{ immediate : true }
{ immediate : true }
@ -231,19 +248,26 @@ onMounted(() => {
if ( ! shouldUseProbeRow . value || miniTableData . value . length === 0 ) {
if ( ! shouldUseProbeRow . value || miniTableData . value . length === 0 ) {
return ;
return ;
}
}
/ / C l e a r p r e v i o u s m e a s u r e m e n t s o e l - t a b l e - v 2 r e c a l c u l a t e s
/ / C l e a r p r e v i o u s m e a s u r e m e n t s s o e l - t a b l e - v 2 r e c a l c u l a t e s
estimatedRowHeight . value = undefined ;
estimatedRowHeight . value = undefined ;
estimatedHeaderHeight . value = undefined ;
await nextTick ( ) ;
await nextTick ( ) ;
/ / W a i t T W O f r a m e s f o r l a y o u t t o s e t t l e
/ / W a i t T W O f r a m e s f o r l a y o u t t o s e t t l e
await new Promise ( ( resolve ) => requestAnimationFrame ( resolve ) ) ;
await new Promise ( ( resolve ) => requestAnimationFrame ( resolve ) ) ;
await new Promise ( ( resolve ) => requestAnimationFrame ( resolve ) ) ;
await new Promise ( ( resolve ) => requestAnimationFrame ( resolve ) ) ;
/ / M e a s u r e h e a d e r h e i g h t
const headerEl = miniTableRef . value ? . querySelector ( ".mini-header" ) ;
const headerHeight = headerEl ? . offsetHeight ;
if ( headerHeight && headerHeight > 0 ) {
estimatedHeaderHeight . value = headerHeight ;
}
/ / M e a s u r e f i r s t r o w h e i g h t
/ / M e a s u r e f i r s t r o w h e i g h t
const firstRow = miniTableRef . value ? . querySelector ( ".mini-row" ) ;
const firstRow = miniTableRef . value ? . querySelector ( ".mini-row:not(.mini-header) " ) ;
const height = firstRow ? . offsetHeight ;
const rowH eight = firstRow ? . offsetHeight ;
if ( height && height > 0 ) {
if ( rowHeight && rowH eight > 0 ) {
estimatedRowHeight . value = height ;
estimatedRowHeight . value = rowH eight;
}
}
} , 10 0) ;
} , 5 0) ;
/ / U s e R e s i z e O b s e r v e r o n . m y - t a b l e t o d e t e c t w i d t h c h a n g e s
/ / U s e R e s i z e O b s e r v e r o n . m y - t a b l e t o d e t e c t w i d t h c h a n g e s
/ / T h i s i s b e t t e r t h a n w i n d o w r e s i z e b e c a u s e i t o n l y f i r e s w h e n O U R c o n t a i n e r c h a n g e s
/ / T h i s i s b e t t e r t h a n w i n d o w r e s i z e b e c a u s e i t o n l y f i r e s w h e n O U R c o n t a i n e r c h a n g e s
@ -504,6 +528,16 @@ const getMiniCellStyle = (item: TableColumn): Record<string, string> => {
overflow : hidden ;
overflow : hidden ;
}
}
. mini - header {
background : v - bind ( "state.style.tableHeadBg" ) ;
font - weight : bold ;
}
. mini - header - content {
overflow : hidden ;
text - overflow : ellipsis ;
}
. mini - cell {
. mini - cell {
box - sizing : border - box ;
box - sizing : border - box ;
overflow : hidden ;
overflow : hidden ;