UNPKG

react-photo-album

Version:

Responsive photo gallery component for React

249 lines (246 loc) 10.9 kB
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 };