import { type ForwardedRef, type ReactNode, forwardRef, type CSSProperties, } from 'react'; import type { Spacing } from '../../../types'; import { List, type ListProps } from '../../atoms'; import styles from './grid.module.scss'; export type GridProps = Omit< ListProps, 'children' | 'hideMarker' | 'isHierarchical' | 'isInline' | 'spacing' > & { /** * How the items should be aligned? * * @default undefined // The default behavior is `stretch`. */ alignItems?: 'center' | 'end' | 'start'; /** * The grid items. */ children: ReactNode; /** * Control the number of column. * * @default 'auto-fit' */ col?: number | 'auto-fill' | 'auto-fit'; /** * The gap between the items. * * @default null */ gap?: Spacing | null; /** * Should the grid be centered? * * @default false */ isCentered?: boolean; /** * Define a fixed size for each item. * * You should either use `size` or `sizeMax`/`sizeMin` not both. * * @default undefined */ size?: string; /** * Define the maximal size of each item. * * You should either use `size` or `sizeMax`/`sizeMin` not both. * * @default '1fr' */ sizeMax?: string; /** * Define the maximal size of each item. * * You should either use `size` or `sizeMax`/`sizeMin` not both. * * @default 0 */ sizeMin?: 0 | string; }; const GridWithRef = ( { alignItems, children, className = '', col = 'auto-fit', gap, isCentered = false, size, sizeMax, sizeMin, style, ...props }: GridProps, ref?: ForwardedRef ) => { const gridClass = [ styles.wrapper, styles[alignItems ? `wrapper--align-items-${alignItems}` : ''], styles[isCentered ? 'wrapper--is-centered' : ''], styles[size ? 'wrapper--has-fixed-size' : ''], styles[sizeMin ? 'wrapper--has-min-size' : ''], className, ].join(' '); const gridStyles = { ...style, '--col': col, ...(size ? { '--size': size } : {}), ...(sizeMax ? { '--size-max': sizeMax } : {}), ...(sizeMin ? { '--size-min': sizeMin } : {}), ...(gap ? { '--gap': `var(--spacing-${gap})` } : {}), } as CSSProperties; return ( {children} ); }; export const Grid = forwardRef(GridWithRef);