react-photo-album
Version:
Responsive photo gallery component for React
249 lines (246 loc) • 10.9 kB
TypeScript
import React from 'react';
/** Layout type */
type LayoutType = "rows" | "columns" | "masonry";
/** Photo object */
interface Photo extends Image {
/** React `key` attribute. */
key?: string;
/** Image `alt` attribute. */
alt?: string;
/** Image `title` attribute. */
title?: string;
/** Image link URL. */
href?: string;
/** ARIA label for the link and button elements */
label?: string;
/** Optional array of alternative images to be included in the `srcset` attribute. */
srcSet?: Image[];
}
/** Image object */
interface Image {
/** Image source. */
src: string;
/** Image width in pixels. */
width: number;
/** Image height in pixels. */
height: number;
}
/** Common photo album props */
interface CommonPhotoAlbumProps<TPhoto extends Photo = Photo> {
/** An array of photos to display in the photo album. */
photos: TPhoto[];
/** Spacing between images. */
spacing?: ResponsiveParameter;
/** Padding around each image. */
padding?: ResponsiveParameter;
/** Photo album container width in various viewports. */
sizes?: ResponsiveSizes;
/** Photo album layout breakpoints. */
breakpoints?: number[];
/** Default container width in SSR. */
defaultContainerWidth?: number;
/** Photo click callback. */
onClick?: ClickHandler<TPhoto>;
/** Custom render functions. */
render?: ResponsiveParameter<Render<TPhoto>, number | undefined>;
/** Additional HTML attributes to be passed to the rendered elements. */
componentsProps?: ResponsiveParameter<ComponentsProps<TPhoto>, number | undefined>;
/** Fallback skeleton in SSR. */
skeleton?: React.ReactNode;
}
/** Rows photo album props */
interface RowsPhotoAlbumProps<TPhoto extends Photo = Photo> extends CommonPhotoAlbumProps<TPhoto> {
/** Target row height. */
targetRowHeight?: ResponsiveParameter;
/** Additional row constraints. */
rowConstraints?: ResponsiveParameter<RowConstraints>;
}
/** Columns photo album props */
interface ColumnsPhotoAlbumProps<TPhoto extends Photo = Photo> extends CommonPhotoAlbumProps<TPhoto> {
/** Number of columns. */
columns?: ResponsiveParameter;
}
/** Masonry photo album props */
interface MasonryPhotoAlbumProps<TPhoto extends Photo = Photo> extends ColumnsPhotoAlbumProps<TPhoto> {
}
/** Photo album sizes settings */
type ResponsiveSizes = {
/** Default size, e.g. `100vw` or `calc(100vw - 200px)`. */
size: string;
/** Array of sizes at various breakpoints. */
sizes?: {
/** Viewport size media query, e.g. `(max-width: 600px)`. */
viewport: string;
/** Photo album width at a given viewport size, e.g. `calc(100vw - 50px)`. */
size: string;
}[];
};
/** Row constraints */
type RowConstraints = {
/** Minimum number of photos per row. */
minPhotos?: number;
/** Maximum number of photos per row. */
maxPhotos?: number;
/** Maximum row height when there is not enough photos to fill more than one row. */
singleRowMaxHeight?: number;
};
/** Layout model */
type LayoutModel<TPhoto extends Photo = Photo> = {
/** Spacing value. */
spacing: number;
/** Padding value. */
padding: number;
/** Container width. */
containerWidth: number;
/** Layout variables. */
variables?: LayoutVariables;
/** Layout orientation. */
horizontal?: boolean;
/** Layout tracks. */
tracks: {
/** Track variables. */
variables?: LayoutVariables;
/** Photos array. */
photos: {
/** Photo object. */
photo: TPhoto;
/** Photo index in the original `photos` array. */
index: number;
/** Rendered photo width in pixels. */
width: number;
/** Rendered photo height in pixels. */
height: number;
}[];
}[];
};
/** Layout variables */
type LayoutVariables = Record<string, string | number | undefined>;
/** Responsive parameter */
type ResponsiveParameter<Value = number, ContainerWidth = number> = ((containerWidth: ContainerWidth) => Value) | Value;
/** Components props */
type ComponentsProps<TPhoto extends Photo = Photo> = {
/** Additional HTML attributes for the outer `<div>` container. */
container?: ContainerComponentProps;
/** Additional HTML attributes for the row / column `<div>` container. */
track?: TrackComponentProps;
/** Additional HTML attributes for the image `<div>` wrapper. */
wrapper?: WrapperComponentProps<TPhoto>;
/** Additional HTML attributes for the photo `<a>` link. */
link?: LinkComponentProps<TPhoto>;
/** Additional HTML attributes for the photo `<button>` element. */
button?: ButtonComponentProps<TPhoto>;
/** Additional HTML attributes for the photo `<img>` element. */
image?: ImageComponentProps<TPhoto>;
};
/** Container component props */
type ContainerComponentProps = React.ComponentPropsWithoutRef<"div">;
/** Track component props */
type TrackComponentProps = React.ComponentPropsWithoutRef<"div">;
/** Wrapper component props */
type WrapperComponentProps<TPhoto extends Photo = Photo> = ContextAware<React.ComponentPropsWithoutRef<"div">, RenderWrapperContext<TPhoto>>;
/** Link component props */
type LinkComponentProps<TPhoto extends Photo = Photo> = ContextAware<React.ComponentPropsWithoutRef<"a">, RenderLinkContext<TPhoto>>;
/** Button component props */
type ButtonComponentProps<TPhoto extends Photo = Photo> = ContextAware<React.ComponentPropsWithoutRef<"button">, RenderButtonContext<TPhoto>>;
/** Image component props */
type ImageComponentProps<TPhoto extends Photo = Photo> = ContextAware<React.ComponentPropsWithoutRef<"img">, RenderImageContext<TPhoto>>;
/** Click handler */
type ClickHandler<TPhoto extends Photo = Photo> = (props: ClickHandlerProps<TPhoto>) => void;
/** Click callback props */
type ClickHandlerProps<TPhoto extends Photo = Photo> = {
/** Click event. */
event: React.MouseEvent;
/** Photo object. */
photo: TPhoto;
/** Photo index in the original `photos` array. */
index: number;
};
/** Custom render functions */
type Render<TPhoto extends Photo = Photo> = {
/** Custom container render function. */
container?: RenderContainer;
/** Custom track render function. */
track?: RenderTrack;
/** Custom wrapper render function. */
wrapper?: RenderWrapper<TPhoto>;
/** Custom link render function. */
link?: RenderLink<TPhoto>;
/** Custom button render function. */
button?: RenderButton<TPhoto>;
/** Custom image render function. */
image?: RenderImage<TPhoto>;
/** Custom photo render function. */
photo?: RenderPhoto<TPhoto>;
/** Custom extra markup render function. */
extras?: RenderExtras<TPhoto>;
};
/** Render container */
type RenderContainer = RenderFunction<RenderContainerProps>;
/** Render container props */
type RenderContainerProps = React.ComponentPropsWithRef<"div">;
/** Render track */
type RenderTrack = RenderFunction<RenderTrackProps>;
/** Render track props */
type RenderTrackProps = React.ComponentPropsWithoutRef<"div">;
/** Render wrapper */
type RenderWrapper<TPhoto extends Photo = Photo> = RenderFunction<RenderWrapperProps, RenderWrapperContext<TPhoto>>;
/** Render wrapper props */
type RenderWrapperProps = React.ComponentPropsWithoutRef<"div">;
/** Render wrapper context */
type RenderWrapperContext<TPhoto extends Photo = Photo> = RenderPhotoContext<TPhoto>;
/** Render link */
type RenderLink<TPhoto extends Photo = Photo> = RenderFunction<RenderLinkProps, RenderLinkContext<TPhoto>>;
/** Render link props */
type RenderLinkProps = NonOptional<React.ComponentPropsWithoutRef<"a">, "href">;
/** Render link context */
type RenderLinkContext<TPhoto extends Photo = Photo> = RenderPhotoContext<TPhoto>;
/** Render button */
type RenderButton<TPhoto extends Photo = Photo> = RenderFunction<RenderButtonProps, RenderButtonContext<TPhoto>>;
/** Render button props */
type RenderButtonProps = React.ComponentPropsWithoutRef<"button">;
/** Render button context */
type RenderButtonContext<TPhoto extends Photo = Photo> = RenderPhotoContext<TPhoto>;
/** Render image */
type RenderImage<TPhoto extends Photo = Photo> = RenderFunction<RenderImageProps, RenderImageContext<TPhoto>>;
/** Render image props */
type RenderImageProps = NonOptional<React.ComponentPropsWithoutRef<"img">, "src">;
/** Render image context */
type RenderImageContext<TPhoto extends Photo = Photo> = RenderPhotoContext<TPhoto>;
/** Render photo */
type RenderPhoto<TPhoto extends Photo = Photo> = RenderFunction<RenderPhotoProps, RenderPhotoContext<TPhoto>>;
/** Render photo props */
type RenderPhotoProps = {
/** Click callback. */
onClick?: React.MouseEventHandler;
};
/** Render photo context */
type RenderPhotoContext<TPhoto extends Photo = Photo> = {
/** Photo object. */
photo: TPhoto;
/** Photo index in the original `photos` array. */
index: number;
/** Rendered photo width in pixels. */
width: number;
/** Rendered photo height in pixels. */
height: number;
};
/** Render extras */
type RenderExtras<TPhoto extends Photo = Photo> = RenderFunction<object, RenderPhotoContext<TPhoto>>;
/** Render function */
type RenderFunction<Props extends object | void = void, Context extends object | void = void> = [
Context
] extends [void] ? [Props] extends [void] ? () => React.ReactNode : (
/** Component props. */
props: Props) => React.ReactNode : [Props] extends [void] ? never : (
/** Component props. */
props: Props,
/** Rendering context. */
context: Context) => React.ReactNode;
type NonOptional<Props, Keys extends keyof Props> = Required<Pick<Props, Keys>> & Omit<Props, Keys>;
type ContextAware<Props, Context> = Props | ((context: Context) => Props | undefined);
type JSXElement = React.JSX.Element;
type ForwardedRef<T extends HTMLElement = HTMLElement> = React.ForwardedRef<T>;
type ElementRef<T extends HTMLElement = HTMLElement> = {
ref?: React.Ref<T>;
};
export type { ButtonComponentProps, ClickHandler, ClickHandlerProps, ColumnsPhotoAlbumProps, CommonPhotoAlbumProps, ComponentsProps, ContainerComponentProps, ContextAware, ElementRef, ForwardedRef, Image, ImageComponentProps, JSXElement, LayoutModel, LayoutType, LayoutVariables, LinkComponentProps, MasonryPhotoAlbumProps, NonOptional, Photo, Render, RenderButton, RenderButtonContext, RenderButtonProps, RenderContainer, RenderContainerProps, RenderExtras, RenderFunction, RenderImage, RenderImageContext, RenderImageProps, RenderLink, RenderLinkContext, RenderLinkProps, RenderPhoto, RenderPhotoContext, RenderPhotoProps, RenderTrack, RenderTrackProps, RenderWrapper, RenderWrapperContext, RenderWrapperProps, ResponsiveParameter, ResponsiveSizes, RowConstraints, RowsPhotoAlbumProps, TrackComponentProps, WrapperComponentProps };