@@ -101,7 +101,8 @@ export class GridHeaderCell implements m.ClassComponent<GridHeaderCellAttrs> {
101101 PopupMenu ,
102102 {
103103 trigger : m ( Button , {
104- className : 'pf-visible-on-hover pf-grid-header-cell__menu-button' ,
104+ className :
105+ 'pf-visible-on-hover pf-grid-header-cell__menu-button pf-grid--no-measure' ,
105106 icon : Icons . ContextMenuAlt ,
106107 rounded : true ,
107108 ariaLabel : 'Column menu' ,
@@ -227,6 +228,23 @@ export interface GridVirtualization {
227228 readonly rowHeightPx : number ;
228229}
229230
231+ /**
232+ * Imperative API for Grid component.
233+ * Provides methods to control the grid programmatically.
234+ */
235+ export interface GridApi {
236+ /**
237+ * Auto-fit a column to its content width.
238+ * @param columnKey The key of the column to auto-fit
239+ */
240+ autoFitColumn ( columnKey : string ) : void ;
241+
242+ /**
243+ * Auto-fit all columns to their content widths.
244+ */
245+ autoFitAllColumns ( ) : void ;
246+ }
247+
230248/**
231249 * Attributes for the Grid component.
232250 */
@@ -243,6 +261,7 @@ export interface GridAttrs {
243261 to : string | number | undefined ,
244262 position : ReorderPosition ,
245263 ) => void ;
264+ readonly onReady ?: ( api : GridApi ) => void ;
246265}
247266
248267/**
@@ -550,6 +569,38 @@ export class Grid implements m.ClassComponent<GridAttrs> {
550569 } ,
551570 } ,
552571 ] ) ;
572+
573+ // Call onReady callback with imperative API
574+ if ( vnode . attrs . onReady ) {
575+ vnode . attrs . onReady ( {
576+ autoFitColumn : ( columnKey : string ) => {
577+ const gridDom = vnode . dom as HTMLElement ;
578+ const column = columns . find ( ( c ) => c . key === columnKey ) ;
579+ if ( ! column ) return ;
580+
581+ this . measureAndApplyWidths ( gridDom , [
582+ {
583+ key : column . key ,
584+ minWidth : column . minWidth ?? COL_WIDTH_MIN_PX ,
585+ maxWidth : Infinity ,
586+ } ,
587+ ] ) ;
588+ m . redraw ( ) ;
589+ } ,
590+ autoFitAllColumns : ( ) => {
591+ const gridDom = vnode . dom as HTMLElement ;
592+ this . measureAndApplyWidths (
593+ gridDom ,
594+ columns . map ( ( column ) => ( {
595+ key : column . key ,
596+ minWidth : column . minWidth ?? COL_WIDTH_MIN_PX ,
597+ maxWidth : Infinity ,
598+ } ) ) ,
599+ ) ;
600+ m . redraw ( ) ;
601+ } ,
602+ } ) ;
603+ }
553604 }
554605
555606 onupdate ( vnode : m . VnodeDOM < GridAttrs , this> ) {
@@ -596,9 +647,18 @@ export class Grid implements m.ClassComponent<GridAttrs> {
596647 const gridClone = gridDom . cloneNode ( true ) as HTMLElement ;
597648 gridDom . appendChild ( gridClone ) ;
598649
650+ // Hide any elements that are not part of the measurement - these are
651+ // elements with class .pf-grid--no-measure
652+ const noMeasureElements = gridClone . querySelectorAll (
653+ '.pf-grid--no-measure' ,
654+ ) ;
655+ noMeasureElements . forEach ( ( el ) => {
656+ ( el as HTMLElement ) . style . display = 'none' ;
657+ } ) ;
658+
599659 // Now read the actual widths (this will cause a reflow)
600660 // Find all the cells in this column (header + data rows)
601- const allCells = gridClone . querySelectorAll ( `.pf-grid__cell-container` ) ; // TODO pick a better selector for this
661+ const allCells = gridClone . querySelectorAll ( `.pf-grid__cell-container` ) ;
602662
603663 // Only continue if we have more cells than just the header
604664 if ( allCells . length <= columns . length ) {
0 commit comments