UNPKG

@indoqa/style-system

Version:

A style system for React with Typescript typed theme support and several base components.

113 lines 4.66 kB
import * as React from 'react'; import { FelaComponent } from 'react-fela'; import { sortBreakpoints } from '../../theming/sortBreakpoints'; import { createPaddingCSSProps, createStylingCSSProps } from '../base'; import { addUnitIfNeeded, createResponsiveStyles, mergeThemedStyles } from '../utils'; import { GRID_SIZE } from './Col'; import { GridContext } from './GridContext'; import { testGridContext } from './testGridContext'; const calcWidthValue = (size, spacing) => { const spacingWithUnit = addUnitIfNeeded(spacing); const availableSpace = `(100% - ${spacingWithUnit} * ${GRID_SIZE - 1})`; const coveredSpacing = `${spacingWithUnit} * ${size - 1}`; return `calc(${availableSpace} / ${GRID_SIZE} * ${size} + ${coveredSpacing} - 0.01px)`; }; const getEnhancedColStyles = (child, breakpointName, size, willBreakAfter, needsMarginTop, spacing) => { const style = { width: calcWidthValue(size, spacing), marginTop: needsMarginTop ? spacing : 0, marginRight: willBreakAfter ? '0px' : spacing, }; return breakpointName === null ? style : { [breakpointName]: style }; }; const toSizeArray = (size) => { if (Array.isArray(size)) { return size; } return [size]; }; const initializeArray = (length) => { const a = []; for (let i = 0; i < length; i++) { a.push(0); } return a; }; const mergeStyles = (style1, style2) => { if (style2 === null) { return style1; } return [style1, style2]; }; const validateSizes = (sizes, breakpointCount, child) => { if (sizes > breakpointCount + 1) { if (process.env.NODE_ENV !== 'production') { console.warn('There are more Col sizes than breakpoints.', child); } return false; } return true; }; const rewriteCols = (breakpoints, children, spacing) => { const currentRowSize = initializeArray(breakpoints.length + 1); const rowsCount = initializeArray(breakpoints.length + 1); return React.Children.map(children, (child) => { const currentChild = child; const sizes = toSizeArray(currentChild.props.size); if (!validateSizes(sizes.length, breakpoints.length, child)) { return; } const style = currentChild.props.style; const enhancedColStyles = {}; for (let i = 0; i < sizes.length; i++) { const currentBreakpoint = i === 0 ? null : breakpoints[i - 1].name; currentRowSize[i] += sizes[i]; const willOverflow = currentRowSize[i] > GRID_SIZE; if (willOverflow) { currentRowSize[i] = sizes[i]; } const completelyFillsRow = currentRowSize[i] === GRID_SIZE; const needsMarginTop = willOverflow || rowsCount[i] > 0; if (completelyFillsRow || willOverflow) { rowsCount[i]++; } const enhancedColStyle = getEnhancedColStyles(currentChild, currentBreakpoint, sizes[i], completelyFillsRow, needsMarginTop, spacing); Object.assign(enhancedColStyles, enhancedColStyle); } return React.cloneElement((currentChild), { style: mergeStyles(enhancedColStyles, style) }); }); }; function createBaseStyles(props, theme) { return { ...createPaddingCSSProps(props, theme), ...createStylingCSSProps(props, theme), }; } class RowContainer extends React.Component { render() { const rowStyle = ({ style, spacing, ...otherProps }) => ({ ...createResponsiveStyles(otherProps, createBaseStyles), boxSizing: 'border-box', display: 'flex', flexWrap: 'wrap', width: '100%', marginTop: spacing, '&:first-child': { marginTop: 0, }, }); const { style, testId, innerRef, ...otherProps } = this.props; const styles = mergeThemedStyles(rowStyle, style); const renderCols = ({ className, theme }) => (React.createElement("div", { className: className, ref: innerRef, "data-testid": testId }, rewriteCols(sortBreakpoints(theme.breakpoints), this.props.children, this.props.spacing))); return (React.createElement(FelaComponent, { style: styles, ...otherProps }, renderCols)); } } export class ColRow extends React.Component { render() { return (React.createElement(GridContext.Consumer, null, ({ spacing }) => { const child = (React.createElement(RowContainer, { spacing: spacing, ...this.props }, this.props.children)); return testGridContext(spacing, child); })); } } //# sourceMappingURL=ColRow.js.map