2.1.2 • Published 1 year ago

react-column-grid v2.1.2

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

react-column-grid

A simple, lightweight, and terse grid based layout system for React applications. It allows you to quickly generate responsive layouts for a great looking application at any screen size.

The library is built using the CSS Grid Layout system.

It does not currently support css grid templates (which are awesome) but support for this may be added in the future.


Installation

npm

npm install -s react-column-grid

yarn

yarn add react-column-grid

The <Grid /> component can be imported using either

const { Grid } = require('react-column-grid');

OR

const Grid = require('react-column-grid');

Example App

There is an example app included in this repo. To run it first clone the repo and then run

npm install # installs dependencies
npm start # runs the application

# OR

yarn # installs dependencies
yarn start # runs the application

The example app provides some basic layouts and the source code required to produce them.


Getting Started

If you're familiar with either Bootstrap's layout grid or Material UI's components's then the syntax should be familiar.

This example will generate a grid with three evenly spaced columns if the user is on a medium screen (e.g. tablet) but generates three full-width rows when the user is on a smaller screen (e.g. phone, small tablet) and generates three evenly spaced rows that are centered with several columns of white space on a larger screen (e.g. monitor).

// <Grid /> is the default export
import Grid from 'react-column-grid';
// import { Grid } from 'react-column-grid'; <== This also works

export const BasicExample = () => (
    <Grid container>
        <Grid item width={{xs: 12, md: 4, lg: 2}} offset={{lg: 3}}><p>Item 1</p></Grid>
        <Grid item width={{xs: 12, md: 4, lg: 2}}><p>Item 2</p></Grid>
        <Grid item width={{xs: 12, md: 4, lg: 2}}><p>Item 3</p></Grid>
    </Grid>
);

Each <Grid> component can be an item, a container, or both. The root container component wraps all of the item components and provides the layout area. Each item component then determines how many columns it will span using the width prop. By default a row spans 12 columns, so when we set the value width={xs: 12} we are saying that this copmonent should take up a full row on an extra small screen. An item component must be the descendant of a container.

The value width={md: 4} instructs the component to take up 4 columns or 1/3 of the total row when the screen is medium sized.

Finally, when the user's screen is large sized there is an offset of 3 columns placed before the first item and then each item takes up 1/6 of the total width of the container.


Sizes and Breakpoints

The available screen sizes, in ascending order, are:

  • xs: extra-small (0px-599px)
  • sm: small (600px-899px))
  • md: medium (900px-1199px)
  • lg: large (1200px-1535px)
  • xl: extra-large (1536px+)

These breakpoints are based on Material UI's default breakpoints

When no value is defined for a prop that uses breakpoints, the value for the next smallest size is used instead. In the following example the "Box 1" component does not have a width defined for sm so it would use the value of xs which is 12 in this case. The "Box 2" component would use the width value of md for both lg and xl since it is the closest smaller size defined.

<Grid container>
    <Grid item width={{ xs: 12, md: 8, lg: 8, xl: 8 }}>Box 1</Grid>
    <Grid item width={{ xs: 12, sm: 12, md: 8 }}>Box 2</Grid>
</Grid>

See the documentation for a complete list of props that use breakpoints.


Width and Offset

The width property is an object that defines the number of columns an item should span at a given size. For example, if you wanted to define an item that spans the entire screen on a phone but only takes up half the screen on a large monitor you would set width={{ xs: 12, xl: 6 }}.

The offset property defines the number of columns the item should be spaced from its nearest sibling. Two common use cases are to center items horizontally on a row and to shove items to the edge of their container

// Create 2 horizontally centered items
// The formula for a centered item's offset is (12 - width) / 2,
// which in case is (12 - 6) / 2 = 3
<Grid container>
    <Grid item width={{ xs: 6 }} offset={{ xs: 3 }}>Row 1</Grid>
    <Grid item width={{ xs: 6 }} offset={{ xs: 3 }}>Row 2</Grid>
</Grid>
// Create 2 items on the left and right edges of their container
// The offset only needs to be placed on the second item and the
// formula is 12 - width1 - width2, which in this case is
// (12 - 2 - 2) = 8
<Grid container>
    <Grid item width={{ xs: 2 }}>Start</Grid>
    <Grid item width={{ xs: 2 }} offset={{ xs: 8 }}>End</Grid>
</Grid>

For elements that have the same width and/or offset across all screen sizes you can use the shorthand syntax.

// Shorthand syntax for width and offset
<Grid container>
    <Grid item width={6} offset="6">Strings or integers can be used for shorthand</Grid>
</Grid>

Clear and Hide

The clear and hide properties also use breakpoints, but use boolean values instead of numeric ones.

The clear prop defines whether a given item should prevent siblings from being placed after in on the same row. One use case would be to create a grid of items that don't add up to the length of the row.

<Grid container>
    <Grid item width={2}>                       (0,0)</Grid>
    <Grid item width={2}>                       (0,1)</Grid>
    <Grid item width={2} clear={{ xs: true }}>  (0,2)</Grid>
    {/* since the previous item is cleared, the next item will begin
        on a new row even though the total widths of the previous 3
        items does not take up the full span of a row */}
    <Grid item width={2}>                       (1,0)</Grid>
    <Grid item width={2}>                       (1,1)</Grid>
    <Grid item width={2} clear={{ xs: true }}>  (1,2)</Grid>
    <Grid item width={2}>                       (2,0)</Grid>
    <Grid item width={2}>                       (2,1)</Grid>
    <Grid item width={2} clear={{ xs: true }}>  (2,2)</Grid>
</Grid>

The hide prop defines whether an item should be shown at a particular screen size. This is most useful for elements like a "Hamburger Menu" that should only show up when the user is on a smaller device.

<Grid container>
    <Grid item width={{ sm: 12 }} hide={{ xs: true, sm: false }}>
        I show up on small screens and larger
    </Grid>
    <Grid item width={12} hide={{ sm: true }}>
        I only show up on extra small screens
    </Grid>
</Grid>

The clear property can also be a boolean if you want to clear the row at all screen sizes.


<Hidden />

When you want to show/hide an item without creating new layout items you can use the <Hidden /> component. It has a single prop hide which behaves the same as on the <Grid /> component.

    <Grid container>
        <Grid item width={12}>
            <Hidden hide={{ xs: true, sm: false }}>Hide me on extra small screens</Hidden>
        </Grid>
    </Grid>

There is also a shorthand syntax for hiding elements. By passing the desired screen size as a prop you can hide only elements at that breakpoint. Unlike the hide prop where the next smallest screen size value is used by larger screen sizes, this prop only targets the specific screen size passed.

import { Hidden } from 'react-column-grid';

export const HiddenExample = () => (
    <Hidden xs xl>
        <span>Hide me on extra small and extra large screens</span>
    </Hidden>
);

Grid Customization

The default grid layout can be customized for your particular needs. By default it will produce a 12 column grid with breakpoints at 600px, 900px, 1200px, and 1536px and a gap of 1em. The <Grid /> component accepts props to customize all 3 of these behaviors. The customization is ignored if the <Grid /> is not a container. When customized these properties will be used by all <Grid /> descendants in that container's hierarchy.

Breakpoints

The breakpoints prop will set the pixel widths for each breakpoint. It is an array of 4 positive integers in ascending order. This value is only valid when paired with the container prop.

// Creates a great with breakpoints at 500px, 800px, 1000px, and 1500px.
// All descendants of the root container will also use these breakpoints
<Grid breakpoints={[500, 800, 1000, 1500]} container>
    <Grid container item width={{ xs: 12, md: 6}}>
        <Grid item width={6}>I</Grid>
        <Grid item width={6}>Am</Grid>
    </Grid>
    <Grid container item width={{ xs: 12, md: 6 }}>
        <Grid item width={6}>Iron</Grid>
        <Grid item width={6}>Man</Grid>
    </Grid>
</Grid>

Columns

The columns prop will set the number of columns the <Grid /> will display. If this value is set be sure to constrain the width and offset values so the sum is less than or equal to the column count. If the width + offset at a given breakpoint exceeds the columns then no styles will be applied and the item will be placed by the browser using auto layout.

<Grid columns={6} container>
    <Grid item width={3}>I take up half the screen</Grid>
    <Grid item width={3}>I take up half the screen</Grid>
</Grid>

Gap

The gap property allows you to assign the space between each column (often referred to as the "gutter"). This can be a string defining any width or a number in which case the unit will be em.

<Grid container gap={2}>
    <Grid item width={6}>There are 2em between me and my sibling</Grid>
    <Grid item width={6}>There are 2em between me and my sibling</Grid>
</Grid>

<Grid container gap={"30px"}>
    <Grid item width={6}>There are 30px between me and my sibling</Grid>
    <Grid item width={6}>There are 30px between me and my sibling</Grid>
</Grid>

To customize <Grid /> behavior across an entire application it is recommended to use the <GridProvider /> in the root of the application. This component can be used to set the breakpoints, columns, and gap of all grids within its hierarchy. This allows global values to be added without having to set them at the root of each route or page in your application.

import Home from './Home';
import { GridProvider } from 'react-column-grid';

const App = () => (
    <GridProvider breakpoints={[550, 900, 1250, 1600]}} columns={3} gap="1rem">
        <Home />
    </GridProvider>
);

Server Side Rendering

react-column-grid relies on injecting styles into the document. If these components are being used in an environment with Server Side Rendering (such as NextJS) it will prevent the page from loading because the document is not available. The <Grid> and <Hidden> components must be loaded dynamically. The example below demonstrates how to do this within the NextJS framework.

import dynamic from 'next/dynamic';

const Grid = dynamic(() => import('react-column-grid').then((rcg) => rcg.Grid), { ssr: false });

const MyComponent = () => {
    return (
        <Grid container>
            <Grid item offset={{ xs: 0, md: 3 }} width={{ xs: 12, md: 6 }}>
                I was loaded dynamically after the <code>document</code> was available
            </Grid>
        </Grid>
    )
};

Additional Documentation

2.1.2

1 year ago

2.1.1

1 year ago

2.1.0

1 year ago

2.0.0

1 year ago

1.2.0

2 years ago

1.1.0

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago