Skip to content

Commit

Permalink
feat: enhance SSR component styling options
Browse files Browse the repository at this point in the history
  • Loading branch information
igordanchenko committed Jul 2, 2024
1 parent a668225 commit a3e99f2
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 6 deletions.
33 changes: 33 additions & 0 deletions docs/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,39 @@ export default function Gallery() {
}
```

<table class="docs">
<tbody>
<tr>
<td><span class="required">breakpoints</span></td>
<td>number[]</td>
<td>Photo album layout breakpoints.</td>
</tr>
<tr>
<td><span class="required">children</span></td>
<td>ReactElement</td>
<td>Photo album instance, which must be the only child.</td>
</tr>
<tr>
<td>unstyled</td>
<td>boolean</td>
<td>
If `true`, do not include the inline stylesheet. Use this option if you
are using custom styling solution (e.g., Tailwind CSS)
</td>
</tr>
<tr>
<td>classNames</td>
<td>
&#123;<br/>
&nbsp;&nbsp;container?: string;
&nbsp;&nbsp;breakpoints?: &#123; [key: number]: string &#125;;
&#125;
</td>
<td>Custom class names for the container and the breakpoint intervals.</td>
</tr>
</tbody>
</table>

Please share your feedback if you have successfully used this component in your
project or encountered any issues.

Expand Down
23 changes: 18 additions & 5 deletions src/ssr/SSR.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
import type React from "react";
import { cloneElement, isValidElement, useState } from "react";

import { clsx } from "../core/utils";
import { useContainerWidth } from "../client/hooks";
import { StyledBreakpoints, useBreakpoints } from "./breakpoints";
import { CommonPhotoAlbumProps } from "../types";
import { StyledBreakpoints, useBreakpoints } from "./breakpoints/index";

/** SSR component props. */
export type SSRProps = {
/** Photo album layout breakpoints. */
breakpoints: number[];
/** Photo album instance, which must be the only child. */
children: React.ReactElement<Pick<CommonPhotoAlbumProps, "breakpoints" | "defaultContainerWidth">>;
/** If `true`, do not include the inline stylesheet. */
unstyled?: boolean;
/** Custom class names for the container and the breakpoint intervals. */
classNames?: {
/** Custom container class name. */
container?: string;
/** Custom class names for the breakpoint intervals. */
breakpoints?: { [key: number]: string };
};
};

/** Experimental SSR component. */
export default function SSR({ breakpoints: breakpointsProp, children }: SSRProps) {
export default function SSR({ breakpoints: breakpointsProp, unstyled, classNames, children }: SSRProps) {
const { breakpoints, containerClass, breakpointClass } = useBreakpoints("ssr", breakpointsProp);
const { containerRef, containerWidth } = useContainerWidth(breakpoints);
const [hydratedBreakpoint, setHydratedBreakpoint] = useState<number>();
Expand All @@ -27,19 +37,22 @@ export default function SSR({ breakpoints: breakpointsProp, children }: SSRProps

return (
<>
{hydratedBreakpoint === undefined && (
{!unstyled && hydratedBreakpoint === undefined && (
<StyledBreakpoints
breakpoints={breakpoints}
containerClass={containerClass}
breakpointClass={breakpointClass}
/>
)}

<div ref={containerRef} className={containerClass}>
<div ref={containerRef} className={clsx(containerClass, classNames?.container)}>
{breakpoints.map(
(breakpoint) =>
(hydratedBreakpoint === undefined || hydratedBreakpoint === breakpoint) && (
<div key={breakpoint} className={breakpointClass(breakpoint)}>
<div
key={breakpoint}
className={clsx(breakpointClass(breakpoint), classNames?.breakpoints?.[breakpoint])}
>
{cloneElement(children, { breakpoints, defaultContainerWidth: breakpoint })}
</div>
),
Expand Down
27 changes: 26 additions & 1 deletion test/SSR.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { render } from "./test-utils";
import photos from "./photos";

describe("SSR", () => {
const breakpoints = [300, 600, 900];

it("works as expected", () => {
const { getTracks, rerender } = render(
<SSR breakpoints={[]}>
Expand All @@ -13,10 +15,33 @@ describe("SSR", () => {
expect(getTracks().length).toBe(0);

rerender(
<SSR breakpoints={[300, 600, 900]}>
<SSR breakpoints={breakpoints}>
<RowsPhotoAlbum photos={photos.slice(0, 1)} />
</SSR>,
);
expect(getTracks().length).toBe(1);
});

it("supports custom class names", () => {
const { container } = render(
<SSR
unstyled
breakpoints={breakpoints}
classNames={{
container: "container-class",
breakpoints: {
150: "breakpoint-150",
300: "breakpoint-300",
600: "breakpoint-600",
900: "breakpoint-900",
},
}}
>
<RowsPhotoAlbum photos={photos} />
</SSR>,
);

expect(container.querySelector(".container-class")).not.toBeNull();
expect(container.querySelector(".breakpoint-900")).not.toBeNull();
});
});

0 comments on commit a3e99f2

Please sign in to comment.