sendou.ink/app/modules/responsive-masonry/components/ResponsiveMasonry.tsx
Kalle 9e829614ed
Some checks are pending
E2E Tests / e2e (push) Waiting to run
Tests and checks on push / run-checks-and-tests (push) Waiting to run
Updates translation progress / update-translation-progress-issue (push) Waiting to run
Replace react-use dependency with a few helpers
2026-06-12 22:40:50 +03:00

60 lines
1.2 KiB
TypeScript

// adapted from https://github.com/cedricdelpoux/react-responsive-masonry
import React from "react";
import { useWindowSize } from "~/hooks/useWindowSize";
import Masonry from "./Masonry";
const COLUMN_COUNTS = {
L: 3,
M: 2,
S: 1,
};
const BREAKPOINTS = {
L: 900,
M: 750,
S: 350,
} as const;
type Breakpoint = keyof typeof BREAKPOINTS;
const MasonryResponsive = ({
children,
}: {
children: React.ReactNode | React.ReactNode[];
}) => {
const breakpoint = useBreakpoint();
const columnsCount = COLUMN_COUNTS[breakpoint];
return (
<div>
{React.Children.map(children, (child, index) =>
React.cloneElement(child as React.ReactElement<any>, {
key: index,
columnsCount,
}),
)}
</div>
);
};
export function ResponsiveMasonry({ children }: { children: React.ReactNode }) {
return (
<MasonryResponsive>
<Masonry gutter="1rem">{children}</Masonry>
</MasonryResponsive>
);
}
function useBreakpoint(): Breakpoint {
const { width } = useWindowSize();
const ascending = Object.entries(BREAKPOINTS).sort((a, b) => a[1] - b[1]);
return ascending.reduce<Breakpoint>(
(current, [name, minWidth]) =>
width >= minWidth ? (name as Breakpoint) : current,
ascending[0][0] as Breakpoint,
);
}