Flickr's justified-layout in a React hook. Calculate justified layouts to create beautiful image galleries or whatever you want.
npm i use-justified-layout
import useJustifiedLayout from 'use-justified-layout'
import images from './images'
const Gallery = () => {
const [layout] = useJustifiedLayout({
layoutInput: images
})
return (
<div style={{position: "relative", height={layout.containerHeight}}>
{layout.boxes.map(({width, height, top, left}, index) => (
<img
width={width}
height={height}
style={{ top, left, position: "absolute" }}
src={images[index].url}
/>
))}
</div>
)
}
useJustifiedLayout
returns and array of two elements: [layout, layoutIsReady]
-
layoutIsReady
: aboolean
that indicates whether or not thelayout
calculation is ready. Useful in cases where you want to show a loader to the user. -
layout
: theLayoutGeometry
object returned by the originaljustified-layout
library. The type is defined as follow:type LayoutGeometry = { containerHeight: number; widowCount: number; boxes: Box[]; };
-
containerHeight
is theheight
of the complete layout, it is necessary since you need to useposition: absolute
to display the items. This attribute will help you avoid things to overlap in yourDOM
. -
widowCount
is the number of items at the end of a layout that doesn't make a full row. For example, the next layout will have awidowCount
value of2
. -
boxes
are the calculated attributes for every item in your layout. Abox
has the following shape:type Box = { aspectRatio: number; top: number; width: number; height: number; left: number; };
-
The hooks accepts a object with the following shape:
interface IUseJustifiedLayout {
layoutInput: LayoutInput;
configuration?: LayoutConfiguration;
dependencies?: ReadonlyArray<unknown>;
}
-
layoutInput
: information about the items, necessary to calculate the layout.type AspectRatio = number; type SizeObject = { width: number; height: number; }; type LayoutInput = AspectRatio[] | SizeObject[];
As you can see, you have to options when passing
layoutInput
:-
Aspect ratios:
[1.33, 1, 0.65]
-
Size objects:
[{ width: 400, height: 300 }, { width: 300, height: 300 }, { width: 250, height: 400 }]
-
-
dependencies
: this is an array with the same function as the dependencies array that you pass to anuseEffect
hook. When a value of this array changes, the layout gets recalculated. By default, the layout will recalculate if thelayoutInput
changes. -
configuration
: you can use the following attributes to customize thelayout
output. This table comes from thejustified-layout
library documentation (with a slight modifications), you can see the original here.Name Type Default Description containerWidth number
1060 The width that boxes will be contained within irrelevant of padding. containerPadding number
ContainerPadding
10 boxSpacing number
BoxSpacing
10 targetRowHeight number
0.25 How far row heights can stray from targetRowHeight
.0
would force rows to be thetargetRowHeight
exactly and would likely make it impossible to justify. The value must be between0
and1
maxNumRows number
none Will stop adding rows at this number regardless of how many items still need to be laid out. forceAspectRatio boolean
number
false showWidows boolean
true By default we'll return items at the end of a justified layout even if they don't make a full row. If false
they'll be omitted from the output.fullWidthBreakoutRowCadence boolean
number
false
Please visit the justified-layout
documentation to get more ideas on how to play with the configurations.
WIP :)