UNPKG

@heroui/image

Version:

A simple image component

127 lines (124 loc) 3.78 kB
"use client"; // src/use-image.ts import { useCallback } from "react"; import { mapPropsVariants, useProviderContext } from "@heroui/system"; import { image } from "@heroui/theme"; import { useDOMRef } from "@heroui/react-utils"; import { clsx, dataAttr, objectToDeps } from "@heroui/shared-utils"; import { useImage as useImageBase } from "@heroui/use-image"; import { useMemo } from "react"; function useImage(originalProps) { var _a, _b; const globalContext = useProviderContext(); const [props, variantProps] = mapPropsVariants(originalProps, image.variantKeys); const { ref, as, src, className, classNames, loading, isBlurred, fallbackSrc, isLoading: isLoadingProp, disableSkeleton = !!fallbackSrc, removeWrapper = false, onError, onLoad, srcSet, sizes, crossOrigin, ...otherProps } = props; const imageStatus = useImageBase({ src, loading, onError, onLoad, ignoreFallback: false, srcSet, sizes, crossOrigin }); const disableAnimation = (_b = (_a = originalProps.disableAnimation) != null ? _a : globalContext == null ? void 0 : globalContext.disableAnimation) != null ? _b : false; const isImgLoaded = imageStatus === "loaded" && !isLoadingProp; const isLoading = imageStatus === "loading" || isLoadingProp; const isZoomed = originalProps.isZoomed; const Component = as || "img"; const domRef = useDOMRef(ref); const { w, h } = useMemo(() => { return { w: props.width ? typeof props.width === "number" ? `${props.width}px` : props.width : "fit-content", h: props.height ? typeof props.height === "number" ? `${props.height}px` : props.height : "auto" }; }, [props == null ? void 0 : props.width, props == null ? void 0 : props.height]); const showFallback = (!src || !isImgLoaded) && !!fallbackSrc; const showSkeleton = isLoading && !disableSkeleton; const slots = useMemo( () => image({ ...variantProps, disableAnimation, showSkeleton }), [objectToDeps(variantProps), disableAnimation, showSkeleton] ); const baseStyles = clsx(className, classNames == null ? void 0 : classNames.img); const getImgProps = (props2 = {}) => { const imgStyles = clsx(baseStyles, props2 == null ? void 0 : props2.className); return { src, ref: domRef, "data-loaded": dataAttr(isImgLoaded), className: slots.img({ class: imgStyles }), loading, srcSet, sizes, crossOrigin, ...otherProps, style: { // img has `height: auto` by default // passing the custom height here to override if it is specified ...(otherProps == null ? void 0 : otherProps.height) && { height: h }, ...props2.style, ...otherProps.style } }; }; const getWrapperProps = useCallback(() => { const fallbackStyle = showFallback ? { backgroundImage: `url(${fallbackSrc})` } : {}; return { className: slots.wrapper({ class: classNames == null ? void 0 : classNames.wrapper }), style: { ...fallbackStyle, maxWidth: w } }; }, [slots, showFallback, fallbackSrc, classNames == null ? void 0 : classNames.wrapper, w]); const getBlurredImgProps = useCallback(() => { return { src, "aria-hidden": dataAttr(true), className: slots.blurredImg({ class: classNames == null ? void 0 : classNames.blurredImg }) }; }, [slots, src, classNames == null ? void 0 : classNames.blurredImg]); return { Component, domRef, slots, classNames, isBlurred, disableSkeleton, fallbackSrc, removeWrapper, isZoomed, isLoading, getImgProps, getWrapperProps, getBlurredImgProps }; } export { useImage };