From 9fb6ffadf6ca621a1a4653d3f0b71848148248c0 Mon Sep 17 00:00:00 2001 From: Igor Danchenko <64441155+igordanchenko@users.noreply.github.com> Date: Thu, 8 Dec 2022 20:54:38 -0500 Subject: [PATCH] refactor: refactor types BREAKING CHANGE: rename RowContainerProps type to RenderRowContainerProps BREAKING CHANGE: rename ColumnContainerProps type to RenderColumnContainerProps --- .../renderers/ColumnContainerRenderer.tsx | 13 +- src/components/renderers/PhotoRenderer.tsx | 4 +- .../renderers/RowContainerRenderer.tsx | 8 +- src/types.ts | 203 +++++++++--------- 4 files changed, 112 insertions(+), 116 deletions(-) diff --git a/src/components/renderers/ColumnContainerRenderer.tsx b/src/components/renderers/ColumnContainerRenderer.tsx index 21679f69..c716cdcd 100644 --- a/src/components/renderers/ColumnContainerRenderer.tsx +++ b/src/components/renderers/ColumnContainerRenderer.tsx @@ -1,12 +1,12 @@ import * as React from "react"; import round from "../../utils/round"; -import { ColumnContainerProps, Optional, Photo, RenderColumnContainer } from "../../types"; +import { Optional, Photo, RenderColumnContainer, RenderColumnContainerProps } from "../../types"; const defaultRenderColumnContainer = ({ columnContainerProps, children, -}: React.PropsWithChildren>) =>
{children}
; +}: RenderColumnContainerProps) =>
{children}
; const cssColumnWidth = (props: ColumnContainerRendererProps) => { const { layoutOptions, columnIndex, columnsCount, columnsGaps, columnsRatios } = props; @@ -28,11 +28,10 @@ const cssColumnWidth = (props: ColumnContainerRendererP )}px) * ${round(columnsRatios[columnIndex] / totalRatio, 5)} + ${2 * padding}px)`; }; -type ColumnContainerRendererProps = React.PropsWithChildren< - Optional, "columnContainerProps"> -> & { - renderColumnContainer?: RenderColumnContainer; -}; +type ColumnContainerRendererProps = Optional< + RenderColumnContainerProps, + "columnContainerProps" +> & { renderColumnContainer?: RenderColumnContainer }; const ColumnContainerRenderer = (props: ColumnContainerRendererProps) => { const { diff --git a/src/components/renderers/PhotoRenderer.tsx b/src/components/renderers/PhotoRenderer.tsx index 8f853586..5449ac62 100644 --- a/src/components/renderers/PhotoRenderer.tsx +++ b/src/components/renderers/PhotoRenderer.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import round from "../../utils/round"; -import { LayoutOptions, Photo, PhotoLayout, RenderPhoto, RenderPhotoProps } from "../../types"; +import { ImgElementAttributes, LayoutOptions, Photo, PhotoLayout, RenderPhoto, RenderPhotoProps } from "../../types"; const calcWidth = ( base: string, @@ -56,7 +56,7 @@ type PhotoRendererProps = Omit< RenderPhotoProps, "imageProps" | "renderDefaultPhoto" | "wrapperStyle" > & { - imageProps?: React.HTMLAttributes; + imageProps?: ImgElementAttributes; } & { renderPhoto?: RenderPhoto }; const PhotoRenderer = (props: PhotoRendererProps) => { diff --git a/src/components/renderers/RowContainerRenderer.tsx b/src/components/renderers/RowContainerRenderer.tsx index d6384a3c..c22bd21b 100644 --- a/src/components/renderers/RowContainerRenderer.tsx +++ b/src/components/renderers/RowContainerRenderer.tsx @@ -1,15 +1,13 @@ import * as React from "react"; -import { Optional, Photo, RenderRowContainer, RowContainerProps } from "../../types"; +import { Optional, Photo, RenderRowContainer, RenderRowContainerProps } from "../../types"; const defaultRenderRowContainer = ({ rowContainerProps, children, -}: React.PropsWithChildren>) =>
{children}
; +}: RenderRowContainerProps) =>
{children}
; -type RowContainerRendererProps = React.PropsWithChildren< - Optional, "rowContainerProps"> -> & { +type RowContainerRendererProps = Optional, "rowContainerProps"> & { renderRowContainer?: RenderRowContainer; }; diff --git a/src/types.ts b/src/types.ts index fa7e7e5b..f33edd33 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2,30 +2,39 @@ import * as React from "react"; export type LayoutType = "columns" | "rows" | "masonry"; -export type ClickHandler = ({ - event, - photo, - index, -}: { - event: React.MouseEvent; - photo: T; - index: number; -}) => void; - -export type ResponsiveParameterProvider = (containerWidth: number) => T; - -export type ResponsiveParameter = T | ResponsiveParameterProvider; - -export type ResponsiveSizes = { - /** default size e.g. 100vw or calc(100vw - 200px) */ - size: string; - /** array of sizes at various breakpoint */ - sizes?: { - /** viewport size media query e.g. (max-width: 600px) */ - viewport: string; - /** photo album width at given viewport size e.g. calc(100vw - 50px) */ - size: string; - }[]; +export type PhotoAlbumProps = { + /** An array of photos to display in the photo album. */ + photos: Array; + /** Photo album layout type. */ + layout: LayoutType; + /** A number of columns in the `columns` or `masonry` layout. */ + columns?: ResponsiveParameter; + /** Spacing between images. */ + spacing?: ResponsiveParameter; + /** Padding around each image in the photo album. */ + padding?: ResponsiveParameter; + /** Target row height in the 'rows' layout. */ + targetRowHeight?: ResponsiveParameter; + /** Additional row constraints in the `rows` layout. */ + rowConstraints?: ResponsiveParameter; + /** Photo album container width at various viewport sizes. */ + sizes?: ResponsiveSizes; + /** Photo click callback function. */ + onClick?: ClickHandler; + /** Responsive breakpoints. */ + breakpoints?: number[]; + /** Default container width in SSR. */ + defaultContainerWidth?: number; + /** Additional HTML attributes to be passed to the rendered elements. */ + componentsProps?: ComponentsPropsParameter; + /** Custom photo rendering function. */ + renderPhoto?: RenderPhoto; + /** Custom container rendering function. */ + renderContainer?: RenderContainer; + /** Custom row container rendering function. */ + renderRowContainer?: RenderRowContainer; + /** Custom column container rendering function. */ + renderColumnContainer?: RenderColumnContainer; }; export interface Image { @@ -48,19 +57,6 @@ export interface Photo extends Image { images?: Image[]; } -export type PhotoLayout = { - /** rendered photo width */ - width: number; - /** rendered photo height */ - height: number; - /** photo index in the original `photos` array */ - index: number; - /** photo index in a given row/column */ - photoIndex: number; - /** number of photos in a given row/column */ - photosCount: number; -}; - export type RenderPhotoProps = { /** photo object */ photo: T; @@ -69,52 +65,52 @@ export type RenderPhotoProps = { /** photo album layout options */ layoutOptions: LayoutOptions; /** pre-populated 'img' element attributes */ - imageProps: React.ImgHTMLAttributes & - Required, "src" | "alt" | "style">>; - /** A callback to render the default photo implementation. If `wrapped` is `true`, the image will be styled - * with `width` and `height` set to 100%. Use this option when you already sized image wrapper with image - * dimensions (see `wrapperStyle`) */ - renderDefaultPhoto: (options?: { wrapped?: boolean }) => React.ReactNode; + imageProps: NonOptional; + /** A callback to render the default photo implementation. If `wrapped` is `true`, the image is styled with `width` + * and `height` set to 100%. Use this option when rendering image wrapper styled with wrapperStyle. */ + renderDefaultPhoto: RenderFunction<{ wrapped?: boolean }>; /** CSS styles to properly size image wrapper (i.e.
wrapper) */ wrapperStyle: React.CSSProperties; }; -export type PhotoAlbumProps = { - /** An array of photos to display in the photo album. */ - photos: Array; - /** Photo album layout type. */ - layout: LayoutType; - /** A number of columns in the `columns` or `masonry` layout. */ - columns?: ResponsiveParameter; - /** Spacing between images. */ - spacing?: ResponsiveParameter; - /** Padding around each image in the photo album. */ - padding?: ResponsiveParameter; - /** Target row height in the 'rows' layout. */ - targetRowHeight?: ResponsiveParameter; - /** Additional row constraints */ - rowConstraints?: ResponsiveParameter; - /** Photo album width at various viewport sizes. */ - sizes?: ResponsiveSizes; - /** Photo click callback function. */ - onClick?: ClickHandler; - /** Responsive breakpoints */ - breakpoints?: number[]; - /** Default container width to be used in the server-side render. */ - defaultContainerWidth?: number; - /** Additional HTML attributes to be passed to the rendered elements */ - componentsProps?: ComponentsPropsParameter; - /** Custom photo rendering function. */ - renderPhoto?: RenderPhoto; - /** Custom container rendering function. */ - renderContainer?: RenderContainer; - /** Custom row container rendering function. */ - renderRowContainer?: RenderRowContainer; - /** Custom column container rendering function. */ - renderColumnContainer?: RenderColumnContainer; +export type RenderPhoto = RenderFunction>; + +export type ClickHandlerProps = { + event: React.MouseEvent; + photo: T; + index: number; +}; + +export type ClickHandler = (props: ClickHandlerProps) => void; + +export type ResponsiveParameterProvider = (containerWidth: number) => T; + +export type ResponsiveParameter = T | ResponsiveParameterProvider; + +export type ResponsiveSizes = { + /** default size e.g. 100vw or calc(100vw - 200px) */ + size: string; + /** array of sizes at various breakpoint */ + sizes?: { + /** viewport size media query e.g. (max-width: 600px) */ + viewport: string; + /** photo album width at given viewport size e.g. calc(100vw - 50px) */ + size: string; + }[]; }; -export type RenderPhoto = (props: RenderPhotoProps) => React.ReactNode; +export type PhotoLayout = { + /** rendered photo width */ + width: number; + /** rendered photo height */ + height: number; + /** photo index in the original `photos` array */ + index: number; + /** photo index in a given row/column */ + photoIndex: number; + /** number of photos in a given row/column */ + photosCount: number; +}; export type GenericLayoutOptions = { /** layout spacing (gaps between photos) */ @@ -147,15 +143,22 @@ export type ColumnsLayoutOptions = GenericLayoutOptions export type LayoutOptions = ColumnsLayoutOptions | RowsLayoutOptions; +export type RowConstraints = { + /** minimum number of photos per row in 'rows' layout */ + minPhotos?: number; + /** maximum number of photos per row in 'rows' layout */ + maxPhotos?: number; +}; + export type ComponentsProps = { /** Additional HTML attributes to be passed to the outer container `div` element */ - containerProps?: React.HTMLAttributes; + containerProps?: DivElementAttributes; /** Additional HTML attributes to be passed to the row container `div` element */ - rowContainerProps?: React.HTMLAttributes; + rowContainerProps?: DivElementAttributes; /** Additional HTML attributes to be passed to the column container `div` element */ - columnContainerProps?: React.HTMLAttributes; + columnContainerProps?: DivElementAttributes; /** Additional HTML attributes to be passed to the photo `img` element */ - imageProps?: React.ImgHTMLAttributes; + imageProps?: ImgElementAttributes; }; export type ComponentsPropsParameter = ComponentsProps | ((containerWidth?: number) => ComponentsProps); @@ -164,14 +167,14 @@ export type RenderContainerProps = React.PropsWithChildren<{ /** layout type */ layout: LayoutType; /** pre-populated default container attributes */ - containerProps: React.HTMLAttributes; + containerProps: DivElementAttributes; /** container ref callback */ containerRef: React.RefCallback; }>; -export type RenderContainer = (props: RenderContainerProps) => React.ReactNode; +export type RenderContainer = RenderFunction; -export type RowContainerProps = { +export type RenderRowContainerProps = React.PropsWithChildren<{ /** layout options */ layoutOptions: RowsLayoutOptions; /** row number */ @@ -179,14 +182,12 @@ export type RowContainerProps = { /** total number of rows */ rowsCount: number; /** pre-populated default row container attributes */ - rowContainerProps: React.HTMLAttributes; -}; + rowContainerProps: DivElementAttributes; +}>; -export type RenderRowContainer = ( - props: React.PropsWithChildren> -) => React.ReactNode; +export type RenderRowContainer = RenderFunction>; -export type ColumnContainerProps = { +export type RenderColumnContainerProps = React.PropsWithChildren<{ layoutOptions: ColumnsLayoutOptions; /** column number */ columnIndex: number; @@ -197,19 +198,17 @@ export type ColumnContainerProps = { /** width adjustment ratios of each column */ columnsRatios?: number[]; /** pre-populated default column container attributes */ - columnContainerProps: React.HTMLAttributes; -}; + columnContainerProps: DivElementAttributes; +}>; -export type RenderColumnContainer = ( - props: React.PropsWithChildren> -) => React.ReactNode; +export type RenderColumnContainer = RenderFunction>; -export type RowConstraints = { - /** minimum number of photos per row in 'rows' layout */ - minPhotos?: number; - /** maximum number of photos per row in 'rows' layout */ - maxPhotos?: number; -}; +export type RenderFunction = (props: T) => React.ReactNode; + +export type DivElementAttributes = JSX.IntrinsicElements["div"]; + +export type ImgElementAttributes = JSX.IntrinsicElements["img"]; -/** @internal */ export type Optional = Partial> & Omit; + +export type NonOptional = Required> & Omit;