Skip to content
This repository has been archived by the owner on Jan 22, 2022. It is now read-only.
/ react-listitem-grid Public archive

Utilities and components for responsive card grid layout

License

Notifications You must be signed in to change notification settings

gsong/react-listitem-grid

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

94 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

react-listitem-grid

npm Test and lint status MIT license

Utilities and components for responsive grid layout of list items. See example use cases.

Table of Contents

Installation

npm install react-listitem-grid

This library has minimal peer depencency on @babel/runtime, which is probably already present in your React project.

If you use the React hook and components from this library, you'll also need the react peer dependency.

Should I Use This Library?

This library currently satisfies some very narrow use cases.

List Item Width

βœ… Use This Library

Your list item has a width range constraint. A good example is a result card design that works well with a minimum width of 150px and a maximum width of 350px.

🚫 Don't Use This Library

  • Your list item has a fixed width.
  • Your list item only has minimum width, but can freely grow to any size.

There are much simpler ways (CSS-only if you're using grid) to solve the problem.

List Item Alignment

βœ… Use This Library

Your list items must always left-align within the grid.

🚫 Don't Use This Library

If your list items need to do anything else.

Items Per Row

βœ… Use This Library

You want to maximize either by item width or by number of items per row.

🚫 Don't Use This Library

If you just need to maximize by number of items. There are simpler solutions.

Maximum Number of Rows

βœ… Use This Library

You need to know how many items the grid container will be rendering, based on the optionally specified maximum number of rows. This is useful, for example, to know how many records to request from the back-end API.

What's in This Library?

Utils

There are some JavaScript utilities which can be used in any project.

calculateLayoutSpec()

View source.

This function does all the calculations and returns an object with:

  • itemWidth: The exact pixel width of each list item.
  • rowCount: Number of items per row.
  • desiredItemCount: How many items should be rendered if the maxRows constraint is given. This value is undefined if maxRows is 0 or undefined.
  • containerWidth: only useful for flexbox-based layout, where the actual container size is larger than what appears visually in order to accommodate column gaps.

⚠️ If you decide to use CSS flexbox to render the grid, be sure to pass isFlex: true.

calculateItemWidthWithCount()

View source.

This is used to recalculate the itemWidth once the number of results are known. For example, the container width may be able to fit 5 items across at 300px each. However, there are only 4 items to be displayed, we'll want to display them at their maximum width of 350px instead of at 300px.

flexCompensate

View source.

  • flexCompensate.container() which returns the CSS margin and width values to be applied to the flex container.
  • flexCompensate.item() which returns the CSS margin value to be applied to the flex item.

useCalculateLayout Hook

View source.

A convenience hook which uses ResizeObserver to measure the width of the grid container. It returns all the values from utils.calculateLayoutSpec() plus a containerRef, which you attach as a ref to a grid container in your JSX. E.g.:

import { useCalculateLayout } from "react-listitem-grid";

function MyComponent() {
  const { containerRef, ...calculatedValues } = useCalculateLayout(calParams);
  return <ul ref={containerRef}>...</ul>;
}

This will ensure calculatedValues is updated if <ul> is resized.

You don't need to use this hook if you want to handle things differently, in that case, just use calculateLayoutSpec() directly.

ℹ️ For browsers that do not support ResizeObserver, the library will automatically ponyfill with @juggle/resize-observer via dynamic import.

⚠️ If you decide to use CSS flexbox to render the grid, be sure to pass isFlex: true.

React Components

These components are supplied simply as styling conveniences, you don't have to use them. These components do not use the useCalculateLayout hook, so it's up to you to wire things up. Refer to the source code or the example app to see what props are required.

Each compound component has Container and Item. Container is marked up as <ul> and Item is marked up as <li>.

Each component also comes with its own CSS which must be imported if you want the default layout behavior.

Example:

import { Grid, useCalculateLayout } from "react-listitem-grid";

import "react-listitem-grid/Grid/styles.css";

function MyComponent() {
  const { containerRef, itemWidth } = useCalculateLayout(calParams);

  return (
    <Grid.Container itemWidth={itemWidth} columnGap={16} rowGap={16}>
      {items.map((item) => (
        <Grid.Item key={item.id}>{item.name}</Grid.Item>
      ))}
    </Grid.Container>
  );
}

The components should be flexible enough that you can apply additional styling however you want: regular CSS, CSS modules, CSS-with-JS.

Grid

View source.

If you work with modern browsers that support CSS grid.

Flex

View source.

If you need to support older browsers with iffy or no grid support, e.g. Internet Explorer. This has been tested to work with IE 11.

How Do I Use This Library?

Example App

This repo contains an example app, which shows the effects of making adjustments calculateLayoutSpec()'s params. You can clone this repo and run it locally:

npm run init-dev
npm start

You can also play with the deployed example app.

Typical Workflow

The example app demonstrates a typical workflow of how to use this library.

  1. Get the calculated values based on container width. The easiest way is to use useCalculateLayout by supplying some initial layout specs.

  2. Fetch the data you need for the list items.

  3. Recalculate the item width if needed. This is necessary if the total number of items is less then rowCount (number of items per row).

  4. Use the Grid or Flex components to render out the result.

The following files specifically use this library:

Want to Help?

Check out the task board and how to contribute.

Contributors

Thanks goes to these people (emoji key):


George Song

πŸ’» πŸ“– πŸ’‘ πŸ€” πŸš‡ 🚧 πŸ‘€

Hanna

πŸ’» πŸ“– πŸ’‘ πŸ€”

This project follows the all-contributors specification. Contributions of any kind welcome!

License

MIT