@@ -119,7 +119,7 @@ div(:class="styles.IndexTable")
119119 div( :class ="stickyColumnHeaderClassNames" )
120120 div(
121121 :class ="styles.TableHeading" ,
122- :key ="headings[0].title " ,
122+ :key ="getHeadingKey( headings[0]) " ,
123123 :style ="stickyColumnHeaderStyle" ,
124124 data-index-table-sticky-heading ="true" ,
125125 )
@@ -174,7 +174,7 @@ div(:class="styles.IndexTable")
174174 )
175175 div(
176176 v-for ="heading, index in headings" ,
177- :key ="heading.title " ,
177+ :key ="getHeadingKey( heading) " ,
178178 :class ="stickyHeadingClassName(index)" ,
179179 :style ="renderStickyHeading(index)" ,
180180 data-index-table-sticky-heading ="true" ,
@@ -205,7 +205,7 @@ div(:class="styles.IndexTable")
205205 tr
206206 template(
207207 v-for ="heading, index in headings" ,
208- :key ="`${ heading.title}-${index}` " ,
208+ :key ="getHeadingKey( heading) " ,
209209 )
210210 th(
211211 v-if ="index === 0 && selectable" ,
@@ -365,6 +365,7 @@ const isSmallScreenSelectable = ref(false);
365365const stickyWrapper = ref <HTMLElement | null >(null );
366366const hideScrollContainer = ref (false );
367367const smallScreen = ref (isBreakpointsXS ());
368+ const canFitStickyColumn = ref (true );
368369
369370const tableHeadings = ref <HTMLElement []>([]);
370371const stickyTableHeadings = ref <HTMLElement []>([]);
@@ -384,6 +385,34 @@ const scrollContainerRef = computed(() => {
384385 && scrollableContainerElement .value .scrollableContainerRef ;
385386});
386387
388+ const handleCanFitStickyColumn = () => {
389+ if (! scrollableContainerElement .value || ! tableHeadings .value .length ) {
390+ return ;
391+ }
392+ const scrollableRect =
393+ (scrollableContainerElement .value as any ).getBoundingClientRect ();
394+ const checkboxColumnWidth = selectable
395+ ? tableHeadings .value [0 ].getBoundingClientRect ().width
396+ : 0 ;
397+ const firstStickyColumnWidth =
398+ tableHeadings .value [selectable ? 1 : 0 ].getBoundingClientRect ().width ;
399+ const lastColumnIsNotTheFirst = selectable
400+ ? tableHeadings .value .length > 2
401+ : 1 ;
402+ // Don't consider the last column in the calculations if it's not sticky
403+ const lastStickyColumnWidth =
404+ props .lastColumnSticky && lastColumnIsNotTheFirst
405+ ? tableHeadings .value [
406+ tableHeadings .value .length - 1
407+ ].getBoundingClientRect ().width
408+ : 0 ;
409+ // Secure some space for the remaining columns to be visible
410+ const restOfContentMinWidth = 100 ;
411+
412+ canFitStickyColumn .value = scrollableRect .width >
413+ firstStickyColumnWidth + checkboxColumnWidth + lastStickyColumnWidth + restOfContentMinWidth ;
414+ };
415+
387416const tableBodyRef = (node ) => {
388417 if (node !== null && ! tableInitialized .value ) {
389418 tableInitialized .value = true ;
@@ -517,6 +546,7 @@ const handleResize = () => {
517546 debounceResizeTableScrollbar ();
518547 handleCanScrollRight ();
519548 handleIsSmallScreen ();
549+ handleCanFitStickyColumn ();
520550};
521551
522552const handleScrollContainerScroll = (canScrollLeft , tmpCanScrollRight ) => {
@@ -617,6 +647,11 @@ watch(
617647 checkIsSmallScreenSelectable ,
618648);
619649
650+ watch (
651+ () => [tableInitialized .value ],
652+ handleCanFitStickyColumn ,
653+ )
654+
620655const hasBulkActions = computed (() => Boolean (
621656 (props .promotedBulkActions && props .promotedBulkActions .length > 0 ) ||
622657 (props .bulkActions && props .bulkActions .length > 0 ),
@@ -739,8 +774,11 @@ const tableClassNames = computed(() => classNames(
739774 selectMode .value && styles .disableTextSelection ,
740775 selectMode .value && shouldShowBulkActions .value && styles .selectMode ,
741776 ! selectable ?.value && styles [' Table-unselectable' ],
742- props .lastColumnSticky && styles [' Table-sticky-last' ],
743- props .lastColumnSticky && canScrollRight && styles [' Table-sticky-scrolling' ],
777+ canFitStickyColumn .value && props .lastColumnSticky && styles [' Table-sticky-last' ],
778+ canFitStickyColumn .value && styles [' Table-sticky' ],
779+ canFitStickyColumn .value &&
780+ props .lastColumnSticky &&
781+ canScrollRight .value && styles [' Table-sticky-scrolling' ],
744782));
745783
746784const handleSelectModeToggle = (val : boolean ) => {
@@ -764,6 +802,18 @@ const headingContentClassName = (heading: IndexTableHeading, index: number) => {
764802 );
765803};
766804
805+ const getHeadingKey = (heading : IndexTableHeading ): string => {
806+ if (heading .id ) {
807+ return heading .id ;
808+ }
809+
810+ if (typeof heading .title === ' string' ) {
811+ return heading .title ;
812+ }
813+
814+ return ' ' ;
815+ }
816+
767817const stickyPositioningStyle = (index : number ) => {
768818 return selectable ?.value !== false &&
769819 isSecond (index ) &&
0 commit comments