'use client'; import React, { forwardRef } from 'react'; import { cn, Surface, useEffectiveSurface, surfaceClasses } from '../common'; import { tone as toneTokens, ToneKey, stackGap, StackGapKey } from '../tokens'; type Layout = 'row' | 'grid'; const colsMap: Record = { 1: 'grid-cols-1', 2: 'grid-cols-2', 3: 'grid-cols-1 sm:grid-cols-3', 4: 'grid-cols-2 sm:grid-cols-4', 5: 'grid-cols-2 sm:grid-cols-5', 6: 'grid-cols-2 sm:grid-cols-6', }; export interface PixelStatGroupProps extends React.HTMLAttributes { layout?: Layout; columns?: number; /** Gap between grid cells (stackGap scale). Only applies to layout="grid"; omit for flush cells. */ gap?: StackGapKey; tone?: ToneKey; surface?: Surface; /** Render with surface-aware border + radius chrome. Defaults to true — group needs visible chrome. */ bordered?: boolean; /** Accessible name for the group landmark. Without it, role=group is dropped. */ 'aria-label'?: string; 'aria-labelledby'?: string; children: React.ReactNode; } export const PixelStatGroup = forwardRef(function PixelStatGroup( { layout = 'row', columns = 3, gap, tone = 'neutral', surface: surfaceProp, bordered = true, className, children, ...rest }, ref, ) { const surface = useEffectiveSurface(surfaceProp); const s = surfaceClasses(surface); const t = toneTokens[tone]; const layoutClass = layout === 'row' ? cn('flex flex-row divide-x overflow-x-auto', t.border) : cn('grid', colsMap[columns] ?? colsMap[3], gap !== undefined && stackGap[gap]); const ariaLabel = (rest as { 'aria-label'?: string })['aria-label']; const ariaLabelledBy = (rest as { 'aria-labelledby'?: string })['aria-labelledby']; const hasName = !!(ariaLabel || ariaLabelledBy); return (
{children}
); }); PixelStatGroup.displayName = 'PixelStatGroup';