Skip to content

Instantly share code, notes, and snippets.

@crisu83
Last active December 4, 2020 15:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save crisu83/cc01308c59f6bbe472696bd069639a6c to your computer and use it in GitHub Desktop.
Save crisu83/cc01308c59f6bbe472696bd069639a6c to your computer and use it in GitHub Desktop.
Utility components built on top of Styled System.
// Utility components on top of styled-system.
// Inspired by [Rebass](https://rebassjs.org/) and adopted to our needs.
// See: https://react-typescript-cheatsheet.netlify.app/docs/advanced/patterns_by_usecase
import {Theme} from '@/styles/theme';
import css, {SystemStyleObject} from '@styled-system/css';
import shouldForwardProp from '@styled-system/should-forward-prop';
import {
ComponentPropsWithRef,
ComponentPropsWithoutRef,
ElementType,
FunctionComponent,
} from 'react';
import {
StyledProps as BaseStyledProps,
ThemedStyledInterface,
default as baseStyled,
useTheme as baseUseTheme,
} from 'styled-components';
import {
BorderProps,
ColorProps,
FlexboxProps,
GridProps as StyledSystemGridProps,
LayoutProps,
ShadowProps,
SpaceProps,
TypographyProps,
border,
color,
compose,
flexbox,
grid,
layout,
shadow,
space,
typography,
} from 'styled-system';
export const styled = baseStyled as ThemedStyledInterface<Theme>;
export const useTheme = () => baseUseTheme() as Theme;
export type StyledProps<P = any> = Omit<BaseStyledProps<P>, 'theme'> & {
theme: Theme;
};
type SxProp = SystemStyleObject;
type BaseProps = {
as?: string;
ref?: any;
sx?: SxProp;
variant?: string;
};
const sx = (props: {sx: SxProp; theme: Theme}) => css(props.sx)(props.theme);
export type BoxProps = BaseProps &
BorderProps &
ColorProps &
LayoutProps &
ShadowProps &
SpaceProps &
TypographyProps;
export type BoxPropsWithoutRef<T extends ElementType<any>> = BoxProps &
ComponentPropsWithoutRef<T>;
export type BoxPropsWithRef<T extends ElementType<any>> = BoxProps &
ComponentPropsWithRef<T>;
export const Box: FunctionComponent<BoxPropsWithoutRef<'div'>> = styled(
'div'
).withConfig({
shouldForwardProp,
})(
{
boxSizing: 'border-box',
margin: 0,
minWidth: 0,
},
sx,
compose(border, color, layout, shadow, space, typography)
) as any;
export type FlexProps = BaseProps & BoxPropsWithoutRef<'div'> & FlexboxProps;
export const Flex: FunctionComponent<FlexProps> = styled(Box)(
{
display: 'flex',
},
flexbox
) as any;
export const Column: FunctionComponent<FlexProps> = styled(Flex)({
flexDirection: 'column',
});
export const Row: FunctionComponent<FlexProps> = styled(Flex)({
flexDirection: 'row',
});
export type GridProps = BaseProps & BoxProps & StyledSystemGridProps;
export const Grid: FunctionComponent<GridProps> = styled(Box)(
{
display: 'grid',
},
grid
) as any;
export type TextProps = BaseProps &
BorderProps &
ColorProps &
LayoutProps &
ShadowProps &
SpaceProps &
TypographyProps;
export type TextPropsWithoutRef<
T extends ElementType<any> = any
> = ComponentPropsWithoutRef<T> & TextProps;
export type TextPropsWithRef<
T extends ElementType<any> = any
> = ComponentPropsWithRef<T> & TextProps;
export const Text: FunctionComponent<TextPropsWithoutRef<'span'>> = styled(
'span'
).withConfig({
shouldForwardProp,
})(sx, compose(border, color, layout, space, shadow, typography)) as any;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment