Created
September 10, 2020 23:32
-
-
Save a-x-/1f0564271f6cba4ba548327b3b987e40 to your computer and use it in GitHub Desktop.
Поток вёрстки — React обёртка над flexbox. <Flow row size="1rem"><Button/><Button/></Flow>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { ReactNode } from 'react' | |
import styled from 'styled-components' | |
/** Nice flexbox wrapper */ | |
type CrossAlign = 'start' | 'end' | 'center' | 'stretch' | 'baseline' | |
export interface FlowProps { | |
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?: CrossAlign | |
size: number | string // interval, px | rem | |
inline?: boolean // display: inline-flex; | |
wrap?: boolean // flex-wrap: wrap | |
style?: object | |
[key: string]: any | |
} | |
type BoxProps = { | |
$size: number | string | |
$inline: boolean | undefined | |
$orient: 'row' | 'col' | |
$cross?: CrossAlign | |
} | |
const Box = styled.div<BoxProps>` | |
display: ${(props) => (props.$inline ? 'inline-flex' : 'flex')}; | |
align-items: ${(props) => props.$cross || (props.$inline ? 'flex-start' : undefined)}; | |
> * + * { | |
margin-${(props) => (props.$orient === 'row' ? 'left' : 'top')}: ${(props) => props.$size}; | |
} | |
` | |
export default function Flow(props: FlowProps) { | |
const { children, row, col, wrap, inline, align, crossAlign, size, style, ...rest } = props | |
// если оба одновременно заданы или нет | |
if (row === col) throw new Error('Flow: не установлено направление с помощью одного из пропов: col или row') | |
const cross = crossAlign || (row && 'center') || undefined | |
return ( | |
<Box | |
{...rest} | |
$size={size} | |
$inline={inline} | |
$orient={row ? 'row' : 'col'} | |
$cross={cross} | |
style={{ | |
...style, | |
flexDirection: row ? 'row' : 'column', | |
flexWrap: wrap ? 'wrap' : 'nowrap', | |
justifyContent: align, | |
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