Utilities and components for responsive grid layout of list items. See example use cases.
- Installation
- Should I Use This Library?
- What's in This Library?
- How Do I Use This Library?
- Want to Help?
- Contributors
- License
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.
This library currently satisfies some very narrow use cases.
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.
- 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.
Your list items must always left-align within the grid.
If your list items need to do anything else.
You want to maximize either by item width or by number of items per row.
If you just need to maximize by number of items. There are simpler solutions.
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.
There are some JavaScript utilities which can be used in any project.
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 themaxRows
constraint is given. This value isundefined
ifmaxRows
is0
orundefined
.containerWidth
: only useful for flexbox-based layout, where the actual container size is larger than what appears visually in order to accommodate column gaps.
isFlex: true
.
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.container()
which returns the CSSmargin
andwidth
values to be applied to the flex container.flexCompensate.item()
which returns the CSSmargin
value to be applied to the flex item.
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.
isFlex: true
.
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.
If you work with modern browsers that support CSS grid.
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.
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.
The example app demonstrates a typical workflow of how to use this library.
-
Get the calculated values based on container width. The easiest way is to use
useCalculateLayout
by supplying some initial layout specs. -
Recalculate the item width if needed. This is necessary if the total number of items is less then
rowCount
(number of items per row).
The following files specifically use this library:
Check out the task board and how to contribute.
Thanks goes to these people (emoji key):
George Song π» π π‘ π€ π π§ π |
Hanna π» π π‘ π€ |
This project follows the all-contributors specification. Contributions of any kind welcome!