Skip to content

Instantly share code, notes, and snippets.

@cpojer
Created April 18, 2023 00:50
Show Gist options
  • Save cpojer/6d50e9ae361153efff601d5a48097c2d to your computer and use it in GitHub Desktop.
Save cpojer/6d50e9ae361153efff601d5a48097c2d to your computer and use it in GitHub Desktop.
import Breakpoints from './Breakpoints';
import { css, cx } from '@emotion/css';
import { HTMLAttributes, forwardRef } from 'react';
export type StackProps = {
adaptive?: true;
alignCenter?: true;
center?: true;
children?: React.ReactNode;
className?: string;
end?: true;
gap?: 2 | 8 | 16 | true;
grow?: boolean;
nowrap?: true;
reverse?: true;
selfCenter?: true;
start?: true;
style?: React.CSSProperties;
vertical?: true;
};
const Stack = forwardRef<
HTMLDivElement,
HTMLAttributes<HTMLDivElement> & StackProps
>(
(
{
adaptive,
alignCenter,
center,
className,
end,
gap,
grow = true,
nowrap,
reverse,
selfCenter,
start,
style,
vertical,
...props
},
ref,
) => {
return (
<div
{...props}
className={cx(
baseStyle,
adaptive && adaptiveStyle,
vertical && verticalStyle,
reverse && (vertical ? verticalReverseStyle : reverseStyle),
reverse && adaptive && vertical && adaptiveVerticalReverseStyle,
center && centeredStyle,
start && startStyle,
end && endStyle,
!grow && flexStartStyle,
alignCenter && alignCenterStyle,
selfCenter && selfCenterStyle,
nowrap && nowrapStyle,
className,
)}
ref={ref}
style={gap ? { ...style, gap: gap === true ? defaultGap : gap } : style}
/>
);
},
);
const defaultGap = 8;
const baseStyle = css`
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
`;
const adaptiveStyle = css`
flex-direction: column;
${Breakpoints.sm} {
flex-direction: row;
}
`;
const verticalStyle = css`
flex-direction: column;
`;
const reverseStyle = css`
flex-direction: row-reverse;
`;
const verticalReverseStyle = css`
flex-direction: column-reverse;
`;
const adaptiveVerticalReverseStyle = css`
${Breakpoints.sm} {
flex-direction: row;
}
`;
const centeredStyle = css`
justify-content: center;
`;
const startStyle = css`
justify-content: flex-start;
`;
const nowrapStyle = css`
flex-wrap: nowrap;
`;
const endStyle = css`
justify-content: flex-end;
`;
const flexStartStyle = css`
align-items: flex-start;
`;
const alignCenterStyle = css`
align-items: center;
`;
const selfCenterStyle = css`
align-self: center;
`;
Stack.displayName = 'Stack';
export default Stack;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment