Skip to content

Instantly share code, notes, and snippets.

@kitze
Created April 22, 2020 07:50
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 kitze/1cd3a03a289990722caa43f1fb19de54 to your computer and use it in GitHub Desktop.
Save kitze/1cd3a03a289990722caa43f1fb19de54 to your computer and use it in GitHub Desktop.
chakra layout styled components
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