Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How I (ab)use styled system and and theme-ui together #872

Closed
Bram-Zijp opened this issue Apr 26, 2020 · 1 comment
Closed

How I (ab)use styled system and and theme-ui together #872

Bram-Zijp opened this issue Apr 26, 2020 · 1 comment

Comments

@Bram-Zijp
Copy link

Bram-Zijp commented Apr 26, 2020

This is just an informative notice of how I use the power of theme-ui and styled-sytem together

So I took the AspectRatio component from theme-ui and made it's ratio value responsive like so:

import React from 'react';
import { system, ResponsiveValue } from 'styled-system';
import styled from '@emotion/styled';
import { Box, BoxProps } from '../Box';

export interface AspectRatioProps extends BoxProps {
  /** sets the ratio (example: 4 / 3) */
  ratio: ResponsiveValue<number>;
}

export const ratioSystem = system({
  ratio: {
    property: 'paddingBottom',
    scale: 'space',
    transform: (value) => {
      return `${100 / value}%`;
    },
  },
});

const RatioBox = styled(Box)<AspectRatioProps>`
  ${ratioSystem}
`;

export const AspectRatio: React.ForwardRefExoticComponent<AspectRatioProps> = React.forwardRef(
  ({ ratio = 4 / 3, sx, children, ...props }: AspectRatioProps, ref) => (
    <Box
      ref={ref}
      sx={{
        overflow: 'hidden',
        position: 'relative',
      }}
    >
      <RatioBox
        ratio={ratio}
        sx={{
          height: 0,
          width: '100%',
        }}
      />
      <Box
        {...props}
        sx={{
          bottom: 0,
          left: 0,
          position: 'absolute',
          right: 0,
          top: 0,
          ...sx,
        }}
      >
        {children}
      </Box>
    </Box>
  ),
);

AspectRatio.displayName = 'AspectRatio';

And you can use it like so:

import React from 'react';
import { AspectRatio } from './AspectRatio';

export default {
  title: 'Components|AspectRatio',
};

const Component: React.FC = (props) => <footer {...props} />;

export const Standard: React.FC = () => (
  <AspectRatio
    as={Component}
    ratio={{ _: 4 / 3, lg: 16 / 9 }}
    sx={{
      alignItems: 'center',
      bg: {_:'black', lg: 'white'},
      color: ['white', null, null,  null, 'black'],
      display: 'flex',
      justifyContent: 'center',
      p: 4,
    }}
  >
    <h1>Aspect Ratio</h1>
  </AspectRatio>
);

What do I miss in theme-ui
Theme ui seems to only allow responsive values in the shape of an array where styled system allows object keys to be used too. When you have like 5 breakpoints, the developer experience of this array way of working becomes a pain. Check the bg and color difference in above snippet for example, the bg is easier to write down and parse.

@jxnblk
Copy link
Member

jxnblk commented May 5, 2020

Thanks! Theme UI only supports arrays for responsive values -- you can use standard media query syntax if you prefer plain objects, see also #832

@jxnblk jxnblk closed this as completed May 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants