diff --git a/packages/image/README.md b/packages/image/README.md index 792c1c5..2639f55 100644 --- a/packages/image/README.md +++ b/packages/image/README.md @@ -1,13 +1,64 @@ -# Minima Image Handbook +# Minima Custom Token Image Processor -This package is made to facilitate image composability across the Minima dApp eco-system. +This package is made to facilitate image compatibility across the Minima dApp ecosystem. It holds both a custom React component, `Image`, and a utility methods that allow you to compress, process and parse custom token images seamlessly. -It has both a re-usable React component labelled `Image` and utility methods that can be used independently especially useful for processing, compressing, and fetching images from various sources, including base64 encodings and IPFS/IPNS. -The `Image` tag that can be imported by `import { Image } from "@minima-global/image"` and then using it like: +## Installation +Install `image` using your preferred package manager: +```bash +npm install @minima-global/image +``` -` ` -Otherwise you can have a look at how the Image component was built using the utility functions in the `/utils` folder part of the package. +## Features +- Re-usable React Component, Image +- Utility methods that allow you to compress, parse and process custom token images depending on their format +- It currently handles base64 encoding, IPFS, IPNS and external URLS. +## Documentation + +View the full documentation on [docs.minima.global](https://docs.minima.global/docs/development/using-typescript). + +## Usage + +```tsx +import { Image } from "@minima-global/image"; + +... rest of your component + + +``` + +Independently you have a suite of utility methods that can do things like, + +```tsx +import { DEFAULT_BASE64_IMAGE, fetchIPFSImage, getBase64Image, isBase64Image, isIPFSOrIPNS, isValidUrl } from "@minima-global/image" // [!code highlight] + +... rest of your component + +if (isIPFSOrIPNS(src)) { + const ipfsUrl = await fetchIPFSImage(src) + return ipfsUrl; +} else if (isValidUrl(src)) { + return src; +} else if (isBase64Image(src)) { + const completeBase64Image = getBase64Image(src) + return completeBase64Image +} + +... rest of your component +``` + +You can also compress an image to ensure it fits on-chain and doesn't cause issues for you when making transactions + +```tsx +import { compressImage } from "@minima-global/image"; + +const compressedImage = await compressImage(tokensBase64ImageData); +``` + + +## Contributing + +This project is made better by contributors like you, and we welcome contributions of all sizes - from fixing typos, adding new features and fixing types, please open an issue or submit a pull request, but be sure to read the [contributing guidelines](https://github.com/minima-global/dev-tools/blob/main/CONTRIBUTING.md). diff --git a/packages/image/package.json b/packages/image/package.json index 878d2d5..d4cc8d9 100644 --- a/packages/image/package.json +++ b/packages/image/package.json @@ -1,6 +1,6 @@ { "name": "@minima-global/image", - "version": "1.5.4", + "version": "1.5.5", "type": "module", "main": "dist/index.js", "module": "dist/index.esm.js", diff --git a/packages/image/src/components/Image.tsx b/packages/image/src/components/Image.tsx index 4addf8a..76f5008 100644 --- a/packages/image/src/components/Image.tsx +++ b/packages/image/src/components/Image.tsx @@ -6,13 +6,11 @@ interface ImageProps { src: string alt?: string className?: string + loader?: React.ReactNode | false } -type ImageType = "on-chain" | "external_url" | "ipfs" | "default" - -const Image: React.FC = ({ src, className = "", alt = "Custom token image" }) => { +const Image: React.FC = ({ src, className = "", alt = "Custom token image", loader = false }) => { const [imageData, setImageData] = useState(DEFAULT_BASE64_IMAGE) - const [imageType, setImageType] = useState("default") const [isLoading, setIsLoading] = useState(true) useEffect(() => { @@ -21,22 +19,17 @@ const Image: React.FC = ({ src, className = "", alt = "Custom token if (isIPFSOrIPNS(src)) { try { const ipfsUrl = await fetchIPFSImage(src) - setImageType("ipfs") setImageData(ipfsUrl) } catch (error) { console.error("Failed to fetch IPFS image:", error) - setImageType("default") setImageData(DEFAULT_BASE64_IMAGE) } } else if (isValidUrl(src)) { - setImageType("external_url") setImageData(src) } else if (isBase64Image(src)) { const completeBase64Image = getBase64Image(src) - setImageType("on-chain") setImageData(completeBase64Image) } else { - setImageType("default") setImageData(DEFAULT_BASE64_IMAGE) } setIsLoading(false) @@ -45,23 +38,6 @@ const Image: React.FC = ({ src, className = "", alt = "Custom token processImageSource() }, [src]) - const getWrapperStyle = (): React.CSSProperties => { - const baseStyle: React.CSSProperties = { - position: "relative", - overflow: "hidden", - } - - switch (imageType) { - case "on-chain": - return { ...baseStyle, width: "50px", height: "50px" } - case "external_url": - case "ipfs": - return { ...baseStyle, width: "100%", maxWidth: "300px", height: "300px" } - default: - return { ...baseStyle, width: "100px", height: "100px" } - } - } - const loadingStyle: React.CSSProperties = { position: "absolute", top: 0, @@ -75,30 +51,27 @@ const Image: React.FC = ({ src, className = "", alt = "Custom token animation: "pulse 1.5s infinite ease-in-out", } - const imageStyle: React.CSSProperties = { - width: "100%", - height: "100%", - objectFit: "contain", - padding: imageType === "on-chain" ? "4px" : "0", - } - return ( - + <> {isLoading ? ( - - - + <> + {!loader && + + } + + {loader && loader} + > ) : ( - + )} - + > ) }