Skip to content

Instantly share code, notes, and snippets.

@a-x-
Created September 10, 2020 23:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save a-x-/1f0564271f6cba4ba548327b3b987e40 to your computer and use it in GitHub Desktop.
Save a-x-/1f0564271f6cba4ba548327b3b987e40 to your computer and use it in GitHub Desktop.
Поток вёрстки — React обёртка над flexbox. <Flow row size="1rem"><Button/><Button/></Flow>
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