import React, { useMemo } from 'react'; import clsx from 'clsx'; import { PageGrid, PageGridCol, PageGridRow } from 'shared/components/PageGrid/page-grid'; import { TileLogo, TileLogoProps } from '../../components/TileLogo/TileLogo'; export interface LogoItem extends TileLogoProps {} export interface LogoRectangleGridProps { /** Color variant - determines background color */ variant?: 'gray' | 'green'; /** Heading text (required) */ heading: string; /** Optional description text */ description?: string; /** Array of logo items to display in the grid */ logos: LogoItem[]; /** Additional CSS classes */ className?: string; } /** * Calculates the md and lg offsets for the first tile of each row to right-align the grid. * * This is a 3-tile-per-row grid. To right-align, we offset based on how many tiles are in that row: * * lg (12 columns, each tile = 3 cols): * - 3 tiles in row: offset 3 * - 2 tiles in row: offset 6 * - 1 tile in row: offset 9 * * md (8 columns, each tile = 2 cols): * - 3 tiles in row: offset 2 * - 2 tiles in row: offset 4 * - 1 tile in row: offset 6 * * Only tiles 1-9 (positions 0-8) are right-aligned. 10+ tiles = no offset. * * @param index - The tile's position (0-based) * @param total - Total number of tiles * @returns Object with md and lg offset values for this tile (both 0 if not first of row) */ const calculateTileOffset = (index: number, total: number): { md: number; lg: number } => { // No offset if 10+ tiles total if (total >= 10) return { md: 0, lg: 0 }; // Only first tile of each row gets offset (every 3rd position starting at 0) if (index % 3 !== 0) return { md: 0, lg: 0 }; // Calculate which row this tile is in const row = Math.floor(index / 3); // Calculate how many tiles are in this row const tilesInThisRow = Math.min(3, total - row * 3); // Calculate offset to right-align // lg: (4 - tilesInRow) * 3 → 3 tiles = 3, 2 tiles = 6, 1 tile = 9 // md: (4 - tilesInRow) * 2 → 3 tiles = 2, 2 tiles = 4, 1 tile = 6 const lgOffset = (4 - tilesInThisRow) * 3; const mdOffset = (4 - tilesInThisRow) * 2; return { md: mdOffset, lg: lgOffset }; }; /** * LogoRectangleGrid Component * * A responsive grid pattern for displaying company/partner logos with rectangle tiles * and dynamic offset based on tile count. Features 9:5 aspect ratio rectangle tiles * with 2 color variants and dark mode support. * * Offset Logic (lg breakpoint only, applied to first tile): * - 1 tile: offset 9 * - 2 tiles: offset 6 * - 3 tiles: offset 3 * - 4 tiles: offset 9 * - 5 tiles: offset 6 * - 6 tiles: offset 3 * - 7 tiles: offset 9 * - 8 tiles: offset 6 * - 9 tiles: offset 3 * - 10+ tiles: no offset * * @example * // Basic usage with gray variant * * * @example * // With clickable logos * */ export const LogoRectangleGrid: React.FC = ({ variant = 'gray', heading, description, logos, }) => { // Build class names using BEM with bds namespace const classNames = clsx( 'bds-logo-rectangle-grid', `bds-logo-rectangle-grid--${variant}`, className ); // Memoize offset calculations - only recalculate when logos array changes const logoOffsets = useMemo(() => { const total = logos.length; return logos.map((_, index) => calculateTileOffset(index, total)); }, [logos]); return ( {/* Header Section */}

{heading}

{description &&

{description}

}
{logos.map((logo, index) => { const offset = logoOffsets[index]; const hasOffset = offset.md > 0 || offset.lg > 0; return ( ); })}
); }; export default LogoRectangleGrid;