use-justified-layout v0.0.6
use-justified-layout
Flickr's justified-layout in a React hook. Calculate justified layouts to create beautiful image galleries or whatever you want.

Installation
npm i use-justified-layoutBasic usage
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>
)
}Hook API
Return
useJustifiedLayout returns and array of two elements: [layout, layoutIsReady]
layoutIsReady: abooleanthat indicates whether or not thelayoutcalculation is ready. Useful in cases where you want to show a loader to the user.layout: theLayoutGeometryobject returned by the originaljustified-layoutlibrary. The type is defined as follow:type LayoutGeometry = { containerHeight: number; widowCount: number; boxes: Box[]; };containerHeightis theheightof the complete layout, it is necessary since you need to useposition: absoluteto display the items. This attribute will help you avoid things to overlap in yourDOM.widowCountis the number of items at the end of a layout that doesn't make a full row. For example, the next layout will have awidowCountvalue of2.
boxesare the calculated attributes for every item in your layout. Aboxhas the following shape:type Box = { aspectRatio: number; top: number; width: number; height: number; left: number; };
Params
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 anuseEffecthook. When a value of this array changes, the layout gets recalculated. By default, the layout will recalculate if thelayoutInputchanges.configuration: you can use the following attributes to customize thelayoutoutput. This table comes from thejustified-layoutlibrary documentation (with a slight modifications), you can see the original here.Name Type Default Description containerWidth number1060 The width that boxes will be contained within irrelevant of padding. containerPadding numberContainerPadding10 Provide a single integer to apply padding to all sides or provide an ContainerPaddingobject to apply individual values to each side, it has the following attributes:right,left,topandbottomboxSpacing numberBoxSpacing10 Provide a single integer to apply spacing both horizontally and vertically or provide an BoxSpacingobject to apply individual values to each axis, it has the following attributes:horizontalandverticaltargetRowHeight number0.25 How far row heights can stray from targetRowHeight.0would force rows to be thetargetRowHeightexactly and would likely make it impossible to justify. The value must be between0and1maxNumRows numbernone Will stop adding rows at this number regardless of how many items still need to be laid out. forceAspectRatio booleannumberfalse Provide an aspect ratio here to return everything in that aspect ratio. Makes the values in your input array irrelevant. The length of the array remains relevant. showWidows booleantrue By default we'll return items at the end of a justified layout even if they don't make a full row. If falsethey'll be omitted from the output.fullWidthBreakoutRowCadence booleannumberfalse If you'd like to insert a full width box every nrows you can specify it with this parameter. The box on that row will ignore thetargetRowHeight, make itself as wide ascontainerWidth-containerPaddingand be as tall as its aspect ratio defines. It'll only happen if that item has an aspect ratio >= 1. Best to have a look at the examples to see what this does.
Configuration examples
Please visit the justified-layout documentation to get more ideas on how to play with the configurations.
Demos
WIP :)