import React, { useMemo } from 'react'; import clsx from 'clsx'; import { PageGrid, PageGridRow, PageGridCol } from 'shared/components/PageGrid/page-grid'; import { TileLink, TileLinkProps } from '../TileLinks/TileLink'; import { calculateTileOffset } from 'shared/utils/helpers'; export interface LinkItem extends Omit {} export interface LinkSmallGridProps { /** Color variant - determines tile background color */ variant?: 'gray' | 'lilac'; /** Heading text (required) */ heading: string; /** Optional description text */ description?: string; /** Array of link items to display in the grid */ links: LinkItem[]; /** Additional CSS classes */ className?: string; } /** * LinkSmallGrid Component * * A responsive grid section pattern for displaying navigational links using TileLink components. * Features a heading, optional description, and a grid of clickable tiles with 2 color variants * and full light/dark mode support. * * Grid Layout (12-column grid system): * - Base (< 576px): 1 tile per row (each tile spans 4 of 4 columns = full width) * - MD (576px - 991px): 2 tiles per row (each tile spans 4 of 8 columns = 50% width) * - LG (≥ 992px): 4 tiles per row (each tile spans 3 of 12 columns = 25% width) * * Right-Alignment Logic (applied when < 10 total tiles): * The first tile of each row gets an offset to right-align the grid at LG breakpoint only: * - LG: 1 tile = offset 9, 2 tiles = offset 6, 3 tiles = offset 3, 4 tiles = offset 0 * - 10+ tiles: no offset (left-aligned grid) * - MD and Base: no offset applied * * Each tile uses the TileLink component which features: * - Window shade hover animation * - Arrow icon with animation * - Responsive sizing (64px height at all breakpoints) * - Support for both links (href) and buttons (onClick) * - Gray and Lilac color variants * * @example * // Basic usage with gray variant * * * @example * // Lilac variant with click handlers * navigate('/start') }, * { label: "Examples", href: "/examples" } * ]} * /> */ export const LinkSmallGrid: React.FC = ({ variant = 'gray', heading, description, links, className, }) => { // Build class names using BEM with bds namespace const classNames = clsx( 'bds-link-small-grid', `bds-link-small-grid--${variant}`, className ); // Memoize offset calculations - only recalculate when links array changes const linkOffsets = useMemo(() => { const total = links.length; return links.map((_, index) => calculateTileOffset(index, total)); }, [links]); return (
{/* Header Section */}

{heading}

{description && (

{description}

)}
{links.map((link, index) => { const offset = linkOffsets[index]; const hasOffset = offset.lg > 0; // Use href or label as key, fallback to index const key = link.href || link.label || index; return ( ); })}
); }; export default LinkSmallGrid;