Created
April 22, 2020 07:50
-
-
Save kitze/1cd3a03a289990722caa43f1fb19de54 to your computer and use it in GitHub Desktop.
chakra layout styled components
This file contains 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 { Box as OriginalBox } from "@chakra-ui/core"; | |
import { PseudoBox } from "@chakra-ui/core/dist"; | |
import React from "react"; | |
import styled from "@emotion/styled"; | |
import flex from "styles/flex"; | |
import { fixedHeight, fixedWidth } from "styled-mixins"; | |
import { gridProps, grid } from "styled-mixins"; | |
export interface CommonProps { | |
wrap?: boolean; | |
spaceBetween?: boolean; | |
spaceAround?: boolean; | |
justifyEnd?: boolean; | |
justifyStart?: boolean; | |
flex?: number; | |
spaceFirst?: boolean; | |
spacing?: number | string; | |
spaceBottom?: boolean; | |
alignStart?: boolean; | |
alignItemsStart?: boolean; | |
center?: boolean; | |
centerV?: boolean; | |
centerH?: boolean; | |
noShrink?: boolean; | |
styles?: any; | |
invert?: boolean; | |
reverse?: boolean; | |
fullW?: boolean; | |
fullH?: boolean; | |
} | |
enum margin { | |
horizontal = "marginRight", | |
vertical = "marginBottom", | |
left = "marginLeft", | |
top = "marginTop" | |
} | |
export const Box: React.FC<{ | |
tr?: boolean | number; | |
br?: number; | |
}> = ({ children, tr, br, ...props }) => ( | |
<OriginalBox | |
{...{ | |
...(br && { borderRadius: br }), | |
...(tr && { transition: "all 100ms linear" }), | |
...props | |
}} | |
> | |
{children} | |
</OriginalBox> | |
); | |
const px = a => (a?.includes?.("px") ? a : `${a}px`); | |
const getOppositeDirection = dir => (dir === "horizontal" ? "left" : "top"); | |
export const common = (direction: string, reverse) => (p: CommonProps) => { | |
direction = reverse === true ? getOppositeDirection(direction) : direction; | |
return { | |
...(p.spaceBetween && flex.spaceBetween), | |
...(p.wrap && flex.wrap), | |
...(p.spaceAround && flex.spaceAround), | |
...(p.justifyEnd && flex.justifyEnd), | |
...(p.justifyStart && flex.justifyStart), | |
...(p.alignStart && flex.alignStart), | |
...(p.alignItemsStart && flex.alignItemsStart), | |
...(p.flex && { flex: p.flex }), | |
...(p.spaceFirst && { | |
"& :first-child": { | |
[margin[direction]]: `${px(p.spaceFirst)} !important` | |
} | |
}), | |
...(p.spacing && { | |
"& > *": { | |
[margin[direction]]: `${px(p.spacing)} !important`, | |
...(p.spaceBottom && { marginBottom: `${px(p.spacing)} !important` }) | |
}, | |
"& > *:last-child": { | |
[margin[direction]]: `0 !important`, | |
...(p.spaceBottom && { marginBottom: `0 !important` }) | |
} | |
}), | |
...(p.noShrink && { | |
flexShrink: 0 | |
}), | |
...(p.fullW && { width: "100%" }), | |
...(p.fullH && { height: "100%" }), | |
...(p.styles && p.styles) | |
}; | |
}; | |
const horizontalProps = (props: any) => { | |
const { center, centerV, reverse, centerH } = props; | |
return { | |
...flex.horizontal, | |
...(reverse && flex.horizontalReverse), | |
...(center && flex.centerHorizontal), | |
...(centerV && flex.centerHorizontalV), | |
...(centerH && flex.centerHorizontalH), | |
...common("horizontal", reverse)(props) | |
}; | |
}; | |
const verticalProps = (props: any) => { | |
const { center, reverse, centerV, centerH } = props; | |
return { | |
...flex.vertical, | |
...(reverse && flex.verticalReverse), | |
...(center && flex.centerVertical), | |
...(centerV && flex.centerVerticalV), | |
...(centerH && flex.centerVerticalH), | |
...common("vertical", reverse)(props) | |
}; | |
}; | |
const getHorizontalProps = ({ invert = false, ...rest }) => { | |
return invert === false ? horizontalProps(rest) : verticalProps(rest); | |
}; | |
const getVerticalProps = ({ invert = false, ...rest }) => { | |
return invert === false ? verticalProps(rest) : horizontalProps(rest); | |
}; | |
const spaceUnit = 1; | |
export const Space = styled.div<{ size: number }>(({ size = 1 }) => ({ | |
...fixedHeight(spaceUnit * size), | |
...fixedWidth(spaceUnit * size) | |
})); | |
//@ts-ignore | |
export const Horizontal = styled(PseudoBox)<CommonProps>(getHorizontalProps); | |
//@ts-ignore | |
export const Vertical = styled(PseudoBox)<CommonProps>(getVerticalProps); | |
//@ts-ignore | |
export const Grid = styled(PseudoBox)<gridProps>(grid); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment