@shopify/hydrogen-react
Version:
React components, hooks, and utilities for creating custom Shopify storefronts
105 lines (104 loc) • 3.25 kB
JavaScript
import { getShopifyImageDimensions, shopifyImageLoader, IMG_SRC_SET_SIZES, addImageSizeParametersToUrl } from "./image-size.mjs";
import { jsx } from "react/jsx-runtime";
function Image({
data,
width,
height,
loading,
loader = shopifyImageLoader,
loaderOptions,
widths,
decoding = "async",
...rest
}) {
var _a, _b, _c, _d, _e, _f, _g, _h;
if (!data.url) {
const missingUrlError = `<Image/>: the 'data' prop requires the 'url' property. Image: ${(_a = data.id) != null ? _a : "no ID provided"}`;
{
throw new Error(missingUrlError);
}
}
if (!data.altText && !rest.alt) {
console.warn(`<Image/>: the 'data' prop should have the 'altText' property, or the 'alt' prop, and one of them should not be empty. Image: ${(_b = data.id) != null ? _b : data.url}`);
}
const {
width: imgElementWidth,
height: imgElementHeight
} = getShopifyImageDimensions({
data,
loaderOptions,
elementProps: {
width,
height
}
});
if (!imgElementWidth || !imgElementHeight) {
console.warn(`<Image/>: the 'data' prop requires either 'width' or 'data.width', and 'height' or 'data.height' properties. Image: ${(_c = data.id) != null ? _c : data.url}`);
}
let finalSrc = data.url;
if (loader) {
finalSrc = loader({
...loaderOptions,
src: data.url,
width: imgElementWidth,
height: imgElementHeight
});
if (typeof finalSrc !== "string" || !finalSrc) {
throw new Error(`<Image/>: 'loader' did not return a valid string. Image: ${(_d = data.id) != null ? _d : data.url}`);
}
}
const maxWidth = width && imgElementWidth && width < imgElementWidth ? width : imgElementWidth;
const finalSrcset = (_e = rest.srcSet) != null ? _e : internalImageSrcSet({
...loaderOptions,
widths,
src: data.url,
width: maxWidth,
height: imgElementHeight,
loader
});
return /* @__PURE__ */ jsx("img", {
id: (_f = data.id) != null ? _f : "",
alt: (_h = (_g = data.altText) != null ? _g : rest.alt) != null ? _h : "",
loading: loading != null ? loading : "lazy",
...rest,
src: finalSrc,
width: imgElementWidth != null ? imgElementWidth : void 0,
height: imgElementHeight != null ? imgElementHeight : void 0,
srcSet: finalSrcset,
decoding
});
}
function internalImageSrcSet({
src,
width,
crop,
scale,
widths,
loader,
height
}) {
const hasCustomWidths = widths && Array.isArray(widths);
if (hasCustomWidths && widths.some((size) => isNaN(size))) {
throw new Error(`<Image/>: the 'widths' must be an array of numbers. Image: ${src}`);
}
let aspectRatio = 1;
if (width && height) {
aspectRatio = Number(height) / Number(width);
}
let setSizes = hasCustomWidths ? widths : IMG_SRC_SET_SIZES;
if (!hasCustomWidths && width && width < IMG_SRC_SET_SIZES[IMG_SRC_SET_SIZES.length - 1]) {
setSizes = IMG_SRC_SET_SIZES.filter((size) => size <= width);
}
const srcGenerator = loader ? loader : addImageSizeParametersToUrl;
return setSizes.map((size) => `${srcGenerator({
src,
width: size,
height: crop ? Number(size) * aspectRatio : void 0,
crop,
scale
})} ${size}w`).join(", ");
}
export {
Image
};
//# sourceMappingURL=Image.mjs.map