UNPKG

react-photo-album

Version:

Responsive photo gallery component for React

158 lines (157 loc) 5.07 kB
import { jsx, jsxs } from "react/jsx-runtime"; import { forwardRef, createElement } from "react"; import { clsx, cssClass, cssVar, round, unwrap, srcSetAndSizes } from "../utils/index.js"; function Component({ as, render, context, classes = [], variables = {}, style: styleProp, className: classNameProp, children, ...rest }, ref) { const className = clsx( ...(Array.isArray(classes) ? classes : [classes]).filter((el) => typeof el === "string").map(cssClass), classNameProp ); const style = { ...Object.fromEntries( Object.entries(variables).map(([key, value]) => [ cssVar(key.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase()), typeof value === "number" ? round(value, 5) : value ]) ), ...styleProp }; const props = { style, className, children, ...rest }; if (render) { const rendered = render({ ref, ...props }, context); if (rendered) return rendered; } const Element = as || "div"; return jsx(Element, { ref, ...props }); } const Component$1 = forwardRef(Component); function PhotoComponent({ photo, index, width, height, onClick, render: { wrapper, link, button, image, extras } = {}, componentsProps: { link: linkProps, button: buttonProps, wrapper: wrapperProps, image: imageProps } = {} }, ref) { const { href } = photo; const context = { photo, index, width: round(width, 3), height: round(height, 3) }; let props; if (href) { props = { ...linkProps, as: "a", render: link, classes: ["photo", "link"], href, onClick }; } else if (onClick) { props = { ...buttonProps, as: "button", type: "button", render: button, classes: ["photo", "button"], onClick }; } else { props = { ...wrapperProps, render: wrapper, classes: "photo" }; } return jsxs( Component$1, { ref, variables: { photoWidth: context.width, photoHeight: context.height }, ...{ context, ...props }, children: [ jsx(Component$1, { as: "img", classes: "image", render: image, context, ...imageProps }), extras?.({}, context) ] } ); } const PhotoComponent$1 = forwardRef(PhotoComponent); function StaticPhotoAlbum({ layout, sizes, model, skeleton, onClick: onClickCallback, render: { container, track, photo: renderPhoto, ...restRender } = {}, componentsProps: { container: containerProps, track: trackProps, link: linkProps, button: buttonProps, wrapper: wrapperProps, image: imageProps } = {} }, ref) { const { spacing, padding, containerWidth, tracks, variables, horizontal } = model || {}; return jsxs( Component$1, { role: "group", "aria-label": "Photo album", ...containerProps, variables: { spacing, padding, containerWidth, ...variables }, classes: ["", layout], render: container, ref, children: [ spacing !== void 0 && padding !== void 0 && containerWidth !== void 0 && tracks?.map(({ photos, variables: trackVariables }, trackIndex) => { const trackSize = photos.length; const photosCount = horizontal ? trackSize : tracks.length; return createElement( Component$1, { ...trackProps, key: trackIndex, render: track, classes: "track", variables: { trackSize, ...trackVariables } }, photos.map((context) => { const { photo, index, width } = context; const { key, src, alt, title, label } = photo; const onClick = onClickCallback ? (event) => { onClickCallback({ event, photo, index }); } : void 0; if (renderPhoto) { const rendered = renderPhoto({ onClick }, context); if (rendered) return rendered; } const ariaLabel = (props) => { return label ? { "aria-label": label, ...props } : props; }; return jsx( PhotoComponent$1, { onClick, render: restRender, componentsProps: { image: { loading: "lazy", decoding: "async", src, alt, title, ...srcSetAndSizes(photo, sizes, width, containerWidth, photosCount, spacing, padding), ...unwrap(imageProps, context) }, link: ariaLabel(unwrap(linkProps, context)), button: ariaLabel(unwrap(buttonProps, context)), wrapper: unwrap(wrapperProps, context) }, ...context }, key ?? src ); }) ); }), containerWidth === void 0 && skeleton ] } ); } const StaticPhotoAlbum$1 = forwardRef(StaticPhotoAlbum); export { StaticPhotoAlbum$1 as default };