UNPKG

@spaced-out/ui-design-system

Version:
111 lines (101 loc) 2.59 kB
// @flow strict import * as React from 'react'; import {classify} from '../../utils/classify'; import css from './Grid.module.css'; export type RowProps = { className?: string, children?: React.Node, span?: number, offset?: number, gridType?: 'small' | 'medium' | 'large' | 'autoFill' | 'autoFit', repeatTracks?: string, }; const GRID_SYSTEM_MAP = { small: 24, medium: 12, large: 6, autoFill: 'auto-fill', autoFit: 'auto-fit', }; export const Row = ({ className, children, span = 1, gridType = 'medium', repeatTracks = '1fr', }: RowProps): React.Node => { const gridRepeatCount = GRID_SYSTEM_MAP[gridType]; let columnSpanCount = 0; let lastChildColCount = 0; const childrenWithProps = React.Children.map(children, (child) => { if (React.isValidElement(child)) { const {span = 1, offset = 0} = child.props; if (span < 1) { console.error(`span can not be less than one`); return; } if (offset < 0) { console.error(`offset can not be negative`); return; } lastChildColCount = columnSpanCount; columnSpanCount = lastChildColCount + offset + span; let gridColumnStart = 0, gridColumnEnd = 0; if (gridType === 'autoFill' || gridType === 'autoFit') { gridColumnStart = 'auto'; return React.cloneElement(child, { gridColumnStart, gridColumnEnd: `span ${span}`, }); } else if ( typeof gridRepeatCount === 'number' && columnSpanCount <= gridRepeatCount ) { gridColumnStart = lastChildColCount + offset + 1; return React.cloneElement(child, { gridColumnStart, gridColumnEnd: `span ${span}`, }); } else { console.error(`number of column exceed ${gridRepeatCount}`); } } }); return ( <div data-testid="Grid" className={classify(css.gridRow, className)} style={{ '--grid-repeat-count': gridRepeatCount, '--repeat-tracks': repeatTracks, }} > {childrenWithProps} </div> ); }; export type ColProps = { className?: string, children?: React.Node, span?: number, offset?: number, gridColumnStart?: number, gridColumnEnd?: number, }; export const Col = ({ className, children, gridColumnStart, gridColumnEnd, }: ColProps): React.Node => ( <div className={classify(css.gridColumn, className)} style={{ '--grid-column-start': gridColumnStart, '--grid-column-end': gridColumnEnd, }} > {children} </div> );