@prass/betterimage
Version:
BetterImage is a Next.js-focused library for building optimized image components with advanced features, including fallback animations. It enhances Next.js's built-in Image component, offering seamless optimization and an improved user experience for your
109 lines (104 loc) • 3.16 kB
JavaScript
import {
__name
} from "./chunk-PAWJFY3S.mjs";
// src/better.ts
import React2 from "react";
import { createRoot } from "react-dom/client";
import Image from "next/image";
import { jsx } from "react/jsx-runtime";
// src/context/index.ts
import React from "react";
var BetterContext = React.createContext(
void 0
);
var useBetter = /* @__PURE__ */ __name(() => {
const context = React.useContext(BetterContext);
if (context === void 0) {
throw new Error("useBetter must be used within a BetterProvider");
}
return context;
}, "useBetter");
// src/better.ts
var R = React2.forwardRef(({ ...props }, ref) => {
const [imageStatus, setImageStatus] = React2.useState("idle");
return jsx(BetterContext.Provider, {
value: { imageStatus, setImageStatus },
children: jsx("div", { ...props, ref })
});
});
R.displayName = "BetterVersion";
var I = React2.forwardRef(({ ...props }, ref) => {
const imageStatus = useImageStatus(props);
return imageStatus === "loaded" && jsx(Image, {
...props,
ref
});
});
I.displayName = "Image";
var F = React2.forwardRef(
({ delay, onFailString, ...props }, ref) => {
const [canRender, setCanRender] = React2.useState(delay === void 0);
const { imageStatus } = useBetter();
React2.useEffect(() => {
if (delay !== void 0) {
const timeout = setTimeout(() => {
setCanRender(true);
}, delay);
return () => clearTimeout(timeout);
}
}, [delay]);
return canRender && imageStatus === "error" ? jsx("div", { ...props, ref, children: onFailString || "" }) : canRender && imageStatus !== "loaded" ? jsx("div", { ...props, ref }) : null;
}
);
F.displayName = "Fallback";
var useImageStatus = /* @__PURE__ */ __name((ImageProps) => {
const { imageStatus, setImageStatus } = useBetter();
React2.useEffect(() => {
if (!ImageProps?.src) {
setImageStatus("error");
return;
}
setImageStatus("loading");
const tempImageDiv = document.createElement("div");
tempImageDiv.style.cssText = "position: absolute; visibility: hidden; top: -9999px; left: -9999px;";
document.body.appendChild(tempImageDiv);
const tempImageRoot = createRoot(tempImageDiv);
const handleComplete = /* @__PURE__ */ __name(() => {
setImageStatus("loaded");
cleanup();
}, "handleComplete");
const handleError = /* @__PURE__ */ __name(() => {
setImageStatus("error");
cleanup();
}, "handleError");
const cleanup = /* @__PURE__ */ __name(() => {
tempImageRoot.unmount();
if (tempImageDiv.parentNode) {
document.body.removeChild(tempImageDiv);
}
}, "cleanup");
tempImageRoot.render(
jsx(Image, {
...ImageProps,
alt: Math.random().toString(),
onLoad: handleComplete,
onError: handleError,
priority: true
})
);
return () => {
cleanup();
};
}, [ImageProps?.src, setImageStatus]);
return imageStatus;
}, "useImageStatus");
// src/index.ts
var Root = R;
var Image2 = I;
var Fallback = F;
export {
Root,
Image2 as Image,
Fallback
};
//# sourceMappingURL=chunk-DH3OE7Z4.mjs.map