Skip to content

Commit

Permalink
feat: add experimental ServerPhotoAlbum component
Browse files Browse the repository at this point in the history
  • Loading branch information
igordanchenko committed Jul 2, 2024
1 parent 81b9b02 commit a668225
Show file tree
Hide file tree
Showing 18 changed files with 352 additions and 121 deletions.
7 changes: 7 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
"types": "./dist/scroll/index.d.ts",
"default": "./dist/scroll/index.js"
},
"./server": {
"types": "./dist/server/index.d.ts",
"default": "./dist/server/index.js"
},
"./rows.css": {
"types": "./dist/styles/rows.css.d.ts",
"default": "./dist/styles/rows.css"
Expand Down Expand Up @@ -48,6 +52,9 @@
"scroll": [
"dist/scroll/index.d.ts"
],
"server": [
"dist/server/index.d.ts"
],
"rows.css": [
"dist/styles/rows.css.d.ts"
],
Expand Down
5 changes: 5 additions & 0 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,14 @@ export default {
"client/rows": "src/client/rows/index.ts",
"client/columns": "src/client/columns/index.ts",
"client/masonry": "src/client/masonry/index.ts",
"client/rowsProps": "src/client/rows/resolveRowsProps.ts",
"client/columnsProps": "src/client/columns/resolveColumnsProps.ts",
"client/masonryProps": "src/client/masonry/resolveMasonryProps.ts",
"client/aggregate": "src/client/aggregate/index.ts",
"scroll/index": "src/scroll/index.ts",
"server/index": "src/server/index.ts",
"ssr/index": "src/ssr/index.ts",
"ssr/breakpoints": "src/ssr/breakpoints/index.ts",
},
output: { dir: "dist" },
plugins: [dts()],
Expand Down
8 changes: 4 additions & 4 deletions src/client/aggregate/PhotoAlbum.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import RowsPhotoAlbum from "../rows";
import ColumnsPhotoAlbum from "../columns";
import MasonryPhotoAlbum from "../masonry";
import { ColumnsPhotoAlbumProps, MasonryPhotoAlbumProps, Photo, RowsPhotoAlbumProps } from "../../types";
import { ColumnsPhotoAlbumProps, LayoutType, MasonryPhotoAlbumProps, Photo, RowsPhotoAlbumProps } from "../../types";

type PhotoAlbumProps<TPhoto extends Photo> =
| ({ layout: "rows" } & RowsPhotoAlbumProps<TPhoto>)
| ({ layout: "columns" } & ColumnsPhotoAlbumProps<TPhoto>)
| ({ layout: "masonry" } & MasonryPhotoAlbumProps<TPhoto>);
| ({ layout: Extract<LayoutType, "rows"> } & RowsPhotoAlbumProps<TPhoto>)
| ({ layout: Extract<LayoutType, "columns"> } & ColumnsPhotoAlbumProps<TPhoto>)
| ({ layout: Extract<LayoutType, "masonry"> } & MasonryPhotoAlbumProps<TPhoto>);

export default function PhotoAlbum<TPhoto extends Photo>({ layout, ...rest }: PhotoAlbumProps<TPhoto>) {
if (layout === "rows") return <RowsPhotoAlbum {...rest} />;
Expand Down
27 changes: 4 additions & 23 deletions src/client/columns/ColumnsPhotoAlbum.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,19 @@ import { useMemo } from "react";

import { useContainerWidth } from "../hooks";
import StaticPhotoAlbum from "../../core/static";
import resolveColumnsProps from "./resolveColumnsProps";
import computeColumnsLayout from "../../layouts/columns";
import { resolveCommonProps, resolveResponsiveParameter } from "../../core/utils";
import { ColumnsPhotoAlbumProps, Photo } from "../../types";

function resolveProps<TPhoto extends Photo>(
containerWidth: number | undefined,
{ columns, ...rest }: Pick<ColumnsPhotoAlbumProps<TPhoto>, "spacing" | "padding" | "componentsProps" | "columns">,
) {
return {
columns: resolveResponsiveParameter(columns, containerWidth, [5, 4, 3, 2], 1),
...resolveCommonProps(containerWidth, rest),
};
}

export default function ColumnsPhotoAlbum<TPhoto extends Photo>({
photos,
onClick,
sizes,
breakpoints,
defaultContainerWidth,
skeleton,
...restProps
...rest
}: ColumnsPhotoAlbumProps<TPhoto>) {
const { containerRef, containerWidth } = useContainerWidth(breakpoints, defaultContainerWidth);

const { spacing, padding, componentsProps, render, columns } = resolveProps(containerWidth, restProps);
const { spacing, padding, columns, ...restProps } = resolveColumnsProps(containerWidth, { photos, ...rest });

const model = useMemo(
() =>
Expand All @@ -37,11 +24,5 @@ export default function ColumnsPhotoAlbum<TPhoto extends Photo>({
[photos, spacing, padding, containerWidth, columns],
);

return (
<StaticPhotoAlbum
layout="columns"
ref={containerRef}
{...{ model, componentsProps, render, onClick, sizes, skeleton }}
/>
);
return <StaticPhotoAlbum layout="columns" ref={containerRef} model={model} {...restProps} />;
}
13 changes: 13 additions & 0 deletions src/client/columns/resolveColumnsProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { resolveCommonProps, resolveResponsiveParameter } from "../../core/utils";
import { ColumnsPhotoAlbumProps, Photo } from "../../types";

export default function resolveColumnsProps<TPhoto extends Photo>(
containerWidth: number | undefined,
{ columns, ...rest }: ColumnsPhotoAlbumProps<TPhoto>,
) {
return {
...rest,
...resolveCommonProps(containerWidth, rest),
columns: resolveResponsiveParameter(columns, containerWidth, [5, 4, 3, 2], 1),
};
}
27 changes: 4 additions & 23 deletions src/client/masonry/MasonryPhotoAlbum.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,19 @@ import { useMemo } from "react";

import { useContainerWidth } from "../hooks";
import StaticPhotoAlbum from "../../core/static";
import resolveMasonryProps from "./resolveMasonryProps";
import computeMasonryLayout from "../../layouts/masonry";
import { resolveCommonProps, resolveResponsiveParameter } from "../../core/utils";
import { MasonryPhotoAlbumProps, Photo } from "../../types";

function resolveProps<TPhoto extends Photo>(
containerWidth: number | undefined,
{ columns, ...rest }: Pick<MasonryPhotoAlbumProps<TPhoto>, "spacing" | "padding" | "componentsProps" | "columns">,
) {
return {
columns: resolveResponsiveParameter(columns, containerWidth, [5, 4, 3, 2], 1),
...resolveCommonProps(containerWidth, rest),
};
}

export default function MasonryPhotoAlbum<TPhoto extends Photo>({
photos,
onClick,
sizes,
breakpoints,
defaultContainerWidth,
skeleton,
...restProps
...rest
}: MasonryPhotoAlbumProps<TPhoto>) {
const { containerRef, containerWidth } = useContainerWidth(breakpoints, defaultContainerWidth);

const { spacing, padding, componentsProps, render, columns } = resolveProps(containerWidth, restProps);
const { spacing, padding, columns, ...restProps } = resolveMasonryProps(containerWidth, { photos, ...rest });

const model = useMemo(
() =>
Expand All @@ -37,11 +24,5 @@ export default function MasonryPhotoAlbum<TPhoto extends Photo>({
[photos, spacing, padding, containerWidth, columns],
);

return (
<StaticPhotoAlbum
layout="masonry"
ref={containerRef}
{...{ model, componentsProps, render, onClick, sizes, skeleton }}
/>
);
return <StaticPhotoAlbum layout="masonry" ref={containerRef} model={model} {...restProps} />;
}
13 changes: 13 additions & 0 deletions src/client/masonry/resolveMasonryProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { resolveCommonProps, resolveResponsiveParameter } from "../../core/utils";
import { MasonryPhotoAlbumProps, Photo } from "../../types";

export default function resolveMasonryProps<TPhoto extends Photo>(
containerWidth: number | undefined,
{ columns, ...rest }: MasonryPhotoAlbumProps<TPhoto>,
) {
return {
...rest,
...resolveCommonProps(containerWidth, rest),
columns: resolveResponsiveParameter(columns, containerWidth, [5, 4, 3, 2], 1),
};
}
56 changes: 6 additions & 50 deletions src/client/rows/RowsPhotoAlbum.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,22 @@ import { useMemo } from "react";

import { useContainerWidth } from "../hooks";
import StaticPhotoAlbum from "../../core/static";
import resolveRowsProps from "./resolveRowsProps";
import computeRowsLayout from "../../layouts/rows";
import { resolveCommonProps, resolveResponsiveParameter, unwrapParameter } from "../../core/utils";
import { Photo, RowsPhotoAlbumProps } from "../../types";

function resolveProps<TPhoto extends Photo>(
containerWidth: number | undefined,
{
targetRowHeight,
rowConstraints,
...rest
}: Pick<
RowsPhotoAlbumProps<TPhoto>,
"spacing" | "padding" | "componentsProps" | "targetRowHeight" | "rowConstraints"
>,
) {
return {
targetRowHeight: resolveResponsiveParameter(targetRowHeight, containerWidth, [
(w) => w / 5,
(w) => w / 4,
(w) => w / 3,
(w) => w / 2,
]),
...unwrapParameter(rowConstraints, containerWidth),
...resolveCommonProps(containerWidth, rest),
};
}

export default function RowsPhotoAlbum<TPhoto extends Photo>({
photos,
onClick,
sizes,
breakpoints,
defaultContainerWidth,
skeleton,
...rest
}: RowsPhotoAlbumProps<TPhoto>) {
const { containerRef, containerWidth } = useContainerWidth(breakpoints, defaultContainerWidth);

const { spacing, padding, componentsProps, render, targetRowHeight, minPhotos, maxPhotos, singleRowMaxHeight } =
resolveProps(containerWidth, rest);
const { spacing, padding, targetRowHeight, minPhotos, maxPhotos, ...restProps } = resolveRowsProps(containerWidth, {
photos,
...rest,
});

const model = useMemo(
() =>
Expand All @@ -51,25 +27,5 @@ export default function RowsPhotoAlbum<TPhoto extends Photo>({
[photos, spacing, padding, containerWidth, targetRowHeight, minPhotos, maxPhotos],
);

if (singleRowMaxHeight !== undefined && spacing !== undefined && padding !== undefined) {
const maxWidth = Math.floor(
photos.reduce(
(acc, { width, height }) => acc + (width / height) * singleRowMaxHeight - 2 * padding,
padding * photos.length * 2 + spacing * (photos.length - 1),
),
);

if (maxWidth > 0) {
componentsProps.container = { ...componentsProps.container };
componentsProps.container.style = { maxWidth, ...componentsProps.container.style };
}
}

return (
<StaticPhotoAlbum
layout="rows"
ref={containerRef}
{...{ model, componentsProps, render, onClick, sizes, skeleton }}
/>
);
return <StaticPhotoAlbum layout="rows" ref={containerRef} model={model} {...restProps} />;
}
40 changes: 40 additions & 0 deletions src/client/rows/resolveRowsProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { resolveCommonProps, resolveResponsiveParameter, unwrapParameter } from "../../core/utils";
import { Photo, RowsPhotoAlbumProps } from "../../types";

export default function resolveRowsProps<TPhoto extends Photo>(
containerWidth: number | undefined,
{ photos, targetRowHeight, rowConstraints, ...rest }: RowsPhotoAlbumProps<TPhoto>,
) {
const { spacing, padding, componentsProps, render } = resolveCommonProps(containerWidth, rest);
const { singleRowMaxHeight, minPhotos, maxPhotos } = unwrapParameter(rowConstraints, containerWidth) || {};

if (singleRowMaxHeight !== undefined && spacing !== undefined && padding !== undefined) {
const maxWidth = Math.floor(
photos.reduce(
(acc, { width, height }) => acc + (width / height) * singleRowMaxHeight - 2 * padding,
padding * photos.length * 2 + spacing * (photos.length - 1),
),
);

if (maxWidth > 0) {
componentsProps.container = { ...componentsProps.container };
componentsProps.container.style = { maxWidth, ...componentsProps.container.style };
}
}

return {
...rest,
targetRowHeight: resolveResponsiveParameter(targetRowHeight, containerWidth, [
(w) => w / 5,
(w) => w / 4,
(w) => w / 3,
(w) => w / 2,
]),
render,
spacing,
padding,
minPhotos,
maxPhotos,
componentsProps,
};
}
Loading

0 comments on commit a668225

Please sign in to comment.