by

Travis Waith-Mair

@travisWaithMair

non-traditional.dev

How to achieve layout composition in React

https://www.plex.tv/careers/

How Do We Achieve Layout Composition?

Hero Layout

A Naive Solution

.hero-container {
  /* container styles */
}

.hero-top {
  /* top styles */
}

.hero-left {
  /* left styles */
}

.hero-right {
  /* right styles */
}

/* ect... */

BEM, OOCSS, Functional CSS or Atomic CSS help manage our CSS style sheets at scale.

 

When we approach our layout as something unique for each component, we miss a fantastic opportunity.

CSS methodologies only get you so far

What if I told you CSS layout could be componentized?

Layout Primitives

function Stack() {
  /** vertically stacks elements on top of each other */
}

function Inline() {
  /** horizontally stacks elements in a row */
}

function Split() {
  /** splits the parent's width between two elements */
}

function Cover() {
  /** covers an area and vertically centers its child */
}

function Frame() {
  /** Frames out a media into the correct aspect ratio */
}

Composable Solution

In JSX

export function Hero() {
  return (
    <Stack>
      <Inline>{/* */}</Inline>
      <Split>
        <Cover>
          <Stack>
            <h1>{/* */}</h1>
            <p>{/* */}</p>
            <Inline>
              <button>{/* */}</button>
              <button>{/* */}</button>
            </Inline>
          </Stack>
        </Cover>
        <Frame>
          <img />
        </Frame>
      </Split>
    </Stack>
  );
}

Layout Primitives can be used across our app.

  • A Signup form
  • A Blog Post Feed
  • A Feature Page
  • etc

Bedrock Layout

bedrock-layout.dev

The Lodash of Web Layouts

Stack

Code

export default function Subscribe() {
  return (
    <Stack as="section" gutter="xl">
      <Stack as="header" gutter="md">
        <h2>Subscribe To Our Newsletter</h2>
        <p>
          Subscribe to our newsletter to keep up to date on all our amazing
          products.
        </p>
      </Stack>

      <Stack as="form">
        <Stack as="label" gutter="sm">
          Name
          <input type="text" />
        </Stack>

        <Stack as="label" gutter="sm">
          Email
          <input type="text" />
        </Stack>

        <button>Subscribe</button>
      </Stack>
    </Stack>
  );
}

InlineCluster

InlineCluster

Code

export default function MenuBar() {
  return (
    <Menu>
      <InlineCluster as="nav" gutter="lg" justify="end" align="center">
        <a>Product</a>
        <a>Features</a>
        <a>Marketplace</a>
        <a>Company</a>
        <a>Log in</a>
      </InlineCluster>
    </Menu>
  );
}

Card Line Up

  • The image and heading for all cards need to line up with the other cards in the same row, with content centered.
  • All Images maintain the same aspect ratio
  • Responsive Grid of cards that maintain a min column width

Code

function Card({ imgSrc, title, description }) {
  <Cover
    minHeight="100%"
    gutter="md"
    top={<h3>{title}</h3>}
    bottom={
      <Frame ratio={[16, 9]}>
        <img src={imgSrc} />
      </Frame>
    }
  >
    <p>{description}</p>
  </Cover>;
}
function CardLineup() {
  return (
    <Grid minItemWidth="40ch" gutter="xxl">
      <Card
        imgSrc="/assets/computer"
        title="Hello Apple"
        description="description here"
      />
      <Card
        imgSrc="/assets/computer"
        title="Hello Apple"
        description="description here"
      />
      <Card
        imgSrc="/assets/computer"
        title="Hello Apple"
        description="description here"
      />
    </Grid>
  );
}

Learn More

Thank You React Summit

 

@travisWaithMair

non-traditional.dev

How to achieve layout composition in React - React Summit

By Justin Travis Waith-Mair

How to achieve layout composition in React - React Summit

  • 198