loading...

Lightweight React Linear Layout Component

bsara profile image Brandon Sarà Updated on ・3 min read

TL;DR

A layout component that arranges children in a single row or column using CSS flexbox and has some very nice custom CSS properties with which you can easily set gaps & item sizes.

It's super small and super easy to use.

Licensed under ISC license.

Storybook: https://bsara.gitlab.io/react-linear-layout/
NPM & Docs: https://www.npmjs.com/package/react-linear-layout
Responsive Version: https://www.npmjs.com/package/react-responsive-linear-layout

At it's core, react-linear-layout (AKA LinearLayout) is basically a CSS flexbox. As such, all flexbox properties are valid when styling a LinearLayout.

You may be asking yourself, "If it's just a flexbox, then why not use a flexbox, why even use this component?" Well, I'm glad that you asked. The power of this component comes in its convenience:

  • LinearLayout has some very nice CSS custom properties that make styling item gaps (I.E. margins) and sizing of elements quite a bit more convenient.
  • LinearLayout comes with some sensible CSS defaults.
  • In some ways, it makes the use of a linear layout more declarative (like specifying the direction of the layout via a prop).

Let's see an example:

import React from 'react';
import LinearLayout from 'react-linear-layout';

export default function MyComponent() {
  return (
    <LinearLayout>
      <div>Item 1</div>
      <div>Item 2</div>
      <div>Item 3</div>
    </LinearLayout>
  );
}

The code above with render the three divs one after another, in a horizontal line (horizontal is the default direction). If we want to change the direction, we can specify the direction prop:

import React from 'react';
import LinearLayout from 'react-linear-layout';

export default function MyComponent() {
  return (
    <LinearLayout direction="vertical">
      <div>Item 1</div>
      <div>Item 2</div>
      <div>Item 3</div>
    </LinearLayout>
  );
}

Now, the items will be stacked one on top of another when rendered.

By default, LinearLayout will span it's parent (because it's CSS display property is set to flex). We can make the component render inline by specifying the inline prop:

import React from 'react';
import LinearLayout from 'react-linear-layout';

export default function MyComponent() {
  return (
    <LinearLayout inline>
      <div>Item 1</div>
      <div>Item 2</div>
      <div>Item 3</div>
    </LinearLayout>
  );
}

CSS Custom Properties

LinearLayout has a few CSS custom properties available that make styling the layout's children really easy. Most notable is --linear-layout-item-gap:

import React from 'react';
import LinearLayout from 'react-linear-layout';
import styled from 'styled-components'; // NOTE: You're not required to use styled-components, I just chose it for the example...just because. :)

const StyledLinearLayout = styled(LinearLayout)`
  --linear-layout-item-gap: 10px;
`;

export default function MyComponent() {
  return (
    <StyledLinearLayout>
      <div>Item 1</div>
      <div>Item 2</div>
      <div>Item 3</div>
    </StyledLinearLayout>
  );
}

When rendered, the children of StyledLinearLayout will have a 10 pixel gap in between them. Also, that gap will be split between each item (I.E. the right margin of Item 1 will be5px and the left margin of Item 2 will be 5px).

If you want all of the items to be the same size, or if you want them to all have the same min/max size, then you can use any of these custom properties:

  • --linear-layout-item-size
  • --linear-layout-item-min-size
  • --linear-layout-item-max-size

If direction is set to "horizontal", then the width of all children will be effected. If direction is set to "vertical" then the height of all of the children will be effected.

Default CSS of LinearLayout

There is some sensible default CSS applied to LinearLayout:

NOTE: You can always override any of these defaults via CSS.

  • All content is justified to flex-start.
  • flex-wrap is set to nowrap.
  • flex-grow and flex-shrink of all children are both set to 0 (this ensures that, by default, the list of items is rendered like any list you might expect rather than having each item take up a large portion of space)

Try It Out

There is both a CommonJS and ESM build distributed in the NPM package.

Feel free to try out the public storybook for react-linear-layout here:
https://bsara.gitlab.io/react-linear-layout

You can find the NPM package and docs here:
https://www.npmjs.com/package/react-linear-layout

Find the source here (contributions are always welcome):
https://gitlab.com/bsara/react-linear-layout

The code is licensed under the ISC license.

Check out the responsive version!

I've also created a version that takes care of all of the margin/padding needed for creating a responsive list:

Discussion

pic
Editor guide