From 96826d6b478f0d7fbda4d2ce182f820a273177c6 Mon Sep 17 00:00:00 2001 From: william garrity Date: Thu, 29 Jan 2026 23:25:45 -0500 Subject: [PATCH] feat(AGGrid): add dynamic row and container heights based on size variant - Add rowHeight and headerHeight props to AgGridReact based on size - Add size-based default container heights (xs=280, sm=320, md=400, lg=480, xl=560) - Height prop now optional - defaults to size-appropriate value when not provided - Fix size control in Storybook to properly change row heights (CSS classes alone don't work) - Update sizeToRowHeight mapping to include containerHeight for each size variant Size mapping: - xs: rowHeight=28px, headerHeight=28px, containerHeight=280px - sm: rowHeight=32px, headerHeight=32px, containerHeight=320px - md: rowHeight=40px, headerHeight=40px, containerHeight=400px (default) - lg: rowHeight=48px, headerHeight=48px, containerHeight=480px - xl: rowHeight=56px, headerHeight=56px, containerHeight=560px The height prop can still be explicitly provided to override the default. --- src/components/AGGrid/AGGrid.stories.tsx | 34 ++++++++++++++++++++++-- src/components/AGGrid/AGGrid.tsx | 27 +++++++++++++++++-- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/components/AGGrid/AGGrid.stories.tsx b/src/components/AGGrid/AGGrid.stories.tsx index 4a1b804..e5ac89d 100644 --- a/src/components/AGGrid/AGGrid.stories.tsx +++ b/src/components/AGGrid/AGGrid.stories.tsx @@ -297,7 +297,7 @@ const rowData = [ argTypes: { variant: { control: 'select', - options: ['default', 'bordered', 'striped'], + options: ['default', 'card', 'bordered', 'striped'], description: 'Visual variant of the grid', table: { defaultValue: { summary: 'default' }, @@ -305,7 +305,7 @@ const rowData = [ }, size: { control: 'select', - options: ['sm', 'md', 'lg'], + options: ['xs', 'sm', 'md', 'lg', 'xl'], description: 'Size/density of the grid rows', table: { defaultValue: { summary: 'md' }, @@ -325,6 +325,28 @@ const rowData = [ defaultValue: { summary: 'false' }, }, }, + pagination: { + control: 'boolean', + description: 'Show pagination controls', + }, + resizable: { + control: 'boolean', + description: 'Enable column resizing', + }, + sortable: { + control: 'boolean', + description: 'Enable sorting', + }, + filterable: { + control: 'boolean', + description: 'Enable filtering', + }, + // Disable controls for props that can't be edited via Storybook + gridRef: { control: false }, + ref: { control: false }, + onRowClick: { control: false }, + brandConfig: { control: false }, + rowSelection: { control: false }, }, }; @@ -340,6 +362,11 @@ export const Default: Story = { variant: 'default', size: 'md', height: 400, + loading: false, + pagination: false, + resizable: false, + sortable: false, + filterable: false, columnDefs: basicColumnDefs as ColDef[], rowData: userData, }, @@ -979,6 +1006,9 @@ export const CompanyAndLinksRenderers: Story = { cellRendererParams: { maxVisible: 2, }, + // Provide valueFormatter for array data to prevent AG Grid warning #48 + valueFormatter: (params) => + Array.isArray(params.value) ? params.value.join(', ') : '', }, ]; diff --git a/src/components/AGGrid/AGGrid.tsx b/src/components/AGGrid/AGGrid.tsx index 81a5599..9141596 100644 --- a/src/components/AGGrid/AGGrid.tsx +++ b/src/components/AGGrid/AGGrid.tsx @@ -101,6 +101,18 @@ export interface AGGridProps // Default Column Definitions // ============================================================================ +// Size to pixel height mapping for AG Grid (row heights + default container heights) +const sizeToRowHeight: Record< + string, + { rowHeight: number; headerHeight: number; containerHeight: number } +> = { + xs: { rowHeight: 28, headerHeight: 28, containerHeight: 280 }, + sm: { rowHeight: 32, headerHeight: 32, containerHeight: 320 }, + md: { rowHeight: 40, headerHeight: 40, containerHeight: 400 }, + lg: { rowHeight: 48, headerHeight: 48, containerHeight: 480 }, + xl: { rowHeight: 56, headerHeight: 56, containerHeight: 560 }, +}; + // Enhanced default column definitions with brand awareness const getDefaultColDef = ( sortable: boolean, @@ -158,7 +170,7 @@ function AGGridInner( variant, size, brand, - height = 400, + height, loading = false, columnDefs, rowData, @@ -251,11 +263,20 @@ function AGGridInner( } }, [loading]); + // Get row/header heights based on size prop + const sizeConfig = sizeToRowHeight[size || 'md']; + + // Use provided height or default based on size + const resolvedHeight = height ?? sizeConfig.containerHeight; + return (
( pagination={pagination} paginationPageSize={pagination ? 50 : undefined} paginationPageSizeSelector={pagination ? [25, 50, 100, 200] : undefined} + rowHeight={sizeConfig.rowHeight} + headerHeight={sizeConfig.headerHeight} noRowsOverlayComponent={() => (
{noDataMessage}