Skip to content

Instantly share code, notes, and snippets.

@a-x-
Last active July 21, 2020 14:26
Show Gist options
  • Save a-x-/f189bfbb5e3a053140410d50e78285ac to your computer and use it in GitHub Desktop.
Save a-x-/f189bfbb5e3a053140410d50e78285ac to your computer and use it in GitHub Desktop.
Flexbox wrappper for React
import React, { ReactNode } from 'react';
import styled from 'styled-components';
/**
* Nice flexbox wrapper
* @example <Flow col size="1rem">...</Flow> // 1rem = 1unit = 8px
*/
interface Props {
children: ReactNode,
// direction shortcut
row?: boolean,
col?: boolean,
// justify-content and align-items
// Note: stretch, stretch-evenly — custom properties
// stretch-evenly instead of proportional stretch, make equal items size container fitting
align?: 'start' | 'end' | 'center' | 'space-between' | 'space-around' | 'space-evenly', // | 'stretch' | 'stretch-evenly',
crossAlign?: 'start' | 'end' | 'center' | 'stretch' | 'baseline',
size: number | string, // interval, px | rem
inline?: boolean, // display: inline-flex;
wrap?: boolean, // flex-wrap: wrap
style?: object,
}
const Horizontal = styled.div<{$size: number | string}>`
> * + * {
margin-left: ${ props => props.$size };
}
`;
const Vertical = styled.div<{$size: number | string}>`
> * + * {
margin-top: ${ props => props.$size };
}
`;
export default function Flow ({ children, row, col, wrap, inline, align, crossAlign, size, style, ...props }: Props) {
// если оба одновременно заданы или нет
if (row === col) throw new Error('Установите направление с помощью одного из пропов: col или row');
const cross = row && !crossAlign ? 'center' : crossAlign;
const Box = row ? Horizontal : Vertical;
return <Box {...props} $size={ size } style={{
...style,
display: inline ? 'inline-flex' : 'flex',
flexDirection: row ? 'row' : 'column',
flexWrap: wrap ? 'wrap' : 'nowrap',
justifyContent: align,
alignItems: cross,
whiteSpace: wrap === false ? 'nowrap' : undefined,
}}>
{ children }
</Box>;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment