3.0.0 • Published 5 months ago

mui-image-alter v3.0.0

Weekly downloads
-
License
ISC
Repository
github
Last release
5 months ago

GitHub License npm npm bundle size GitHub Workflow Status Coverage from badge.yml Buy Me A Coffee

If you're already using Material UI v5, why not display your images according to the Material guidelines too?

Illustrations and photographs may load and transition in three phases at staggered durations, rather than relying on opacity changes alone.

Visualize the image fading in, like a print during the photo development process.

- Material guidelines

About the fork

Alter from alternative.

I actually just to make a fork with small modification for my website but somehow I ended changed many things... How it became like this?

Why should I use this?

If you satisfied with original project, you probably not need this. This is for users with a specific need.

To put it simply, you only needed this if:

  • You want to change the component root element, img with other component like Image from next/image.
  • You want to use styled function from styled-components or emotion or MUI on Image component but noticed some style not working properly.^1

^1: This happen on original project because the styles set using style prop. To correct this for original project, you need to use style or wrapperStyle or iconWrapperStyle that provided to overwrite the default style.

Changes in this fork

  • Breaking Changes

    • Height and width prop forwarded to the component root element (by default, img) instead of using CSS to set height and width of component wrapper element. Some alternate image components like next/image actually need for height and width prop.
    • Put all styles that set though style prop in styled for better compability with MUI's styled.
    • No UMD build. Go post an issue if you want UMD to be added.
    • Only named exports. Read this article.
  • Other Changes

    • Rewritten fully in Typescript with types built-in based on MUI component types.
    • Add support to MUI's component prop; That's means you can subtitute component root element with Image from next/image if you want. Component supported are img, img-derived HTML element and component with src prop.
    • Properly export esm and cjs build via package.json exports.
  • Development Changes

    • Use Vite instead of nwb for development and building the library for fast and better developer experience for me!
    • Added unit tests for testing mui-image-alter component. Also, added new Github Action that will automatically run these tests every pull request.

Simple Q & A

  • Q: Why you created this fork?
    A: MUI's styled don't work very well with the original mui-image because some of default styling and it use style prop instead of using styled to set some of the styling. So, I want to modify a little bit... And I end up doing at lot.
    Originally, I want to just post an issue for this but I am suck in comunication. 😅

  • Q: Why you change nwb to Vite?
    A: I just wanted to fork for my own benefit. So, I thought maybe I can write this in TypeScript... but it don't work with nwb. I am so frustrated that I cannot find how to do it and try migarating to Vite instead. (Also, looks like nwb is abandoned too...) It took a lot of work but never thought it work so well... Maybe there is actually a way to use Typescript with nwb but I never regret switching to Vite.

    Vite is so fast!!! 😍

  • Q: Will you intergrate changes from the original project?
    A: Yeah. As many as possible. 💪


1. Install

Install the mui-image-alter peer dependencies first. (Can skip if you already done it.)

If you haven't yet install MUI, please follow the official guide.

Now, you can install the mui-image-alter.

Install from npm

npm install mui-image-alter
yarn add mui-image-alter

Install from repository

Recommended to specify a version tag like this for installation from the repository like below for stability.

npm install github:mddanish00/mui-image-alter#vx.x.xx
yarn add mui-image-alter@github:mddanish00/mui-image-alter#vx.x.xx

Replace x.x.xx with actual tags from here.

2. Use

import { Image } from 'mui-image-alter';

// then

<Image src="my-image.png" />

3. Profit 💰

Note: Profits not guaranteed and Material UI v5 is a peer dependency. If you need to support legacy versions of Material UI, use material-ui-image instead. See the comparison chart below for more.

Usage Examples

You can use mui-image-alter like a regular image.

<Image src="my-image.png" />

Except... it will fade and animate in as the Material guidelines recommend. 🤯

Apply the showLoading prop to add a progress indicator to let your fans know something amazing is coming. You can use the default MUI indicator or bring your own. 😎

<Image src="my-image.png" showLoading />
<Image src="my-image.bmp" showLoading={<MyCustomSpinner />} />

If you want the image to fail silently you can disable the errorIcon, or you can add your own to suit your brand.

<Image src="my-cats.png" errorIcon={null} />
<Image src="my-dogs.png" errorIcon={<MyErrorIcon />} />

If you want to disobey Google 😵 then you can customise the animation and speed via the duration and easing props to any valid CSS property. Duration is always milliseconds.

<Image src="my-fish.png" duration={325} />
<Image src="my-bird.jpg" easing="ease-in-out" />

To add that extra bit of spice 🌶 you can do exactly what Google suggests and apply a small position shift to images as they appear. The direction, distance, and duration (in milliseconds) are up to you.

<Image src="my-lawd.png" shift="left" />
<Image src="my-gawd.jpg" shift="bottom" distance={300} />
<Image src="my-gosh.gif" shift="top" distance="2rem" shiftDuration={320} />

And of course, you can style mui-image like you would a regular image... but with the addition of the MUI v5 sx prop and all the benefits it brings. 😏

<Image src="my-self.jpeg" style={{ borderRadius: 16 }} />
<Image src="my-wife.webp" className="custom-class" />
<Image src="my-exgf.tiff" sx={{ display: { sm: 'none', lg: 'inline' }}} />

If you want to get fancy 💃 you can also add inline styles and additional className's to the root wrapper div and loading/error icon wrapper div, or just target their default className's. This allows for complete customisation of every aspect of the component.

Fork Exclusive Usage

With this fork, you can use MUI's styled normally like this. More info on MUI's official doccumentation.

import { styled } from '@mui/material/styles';
import { Image } from 'mui-image-alter';

const customImage = styled(Image)({
    margin: 0 auto;
    max-width: 100%;
    display: block;
    max-height: 500px;
});

You also can use composition to create custom components.

import { Image, ImageProps } from 'mui-image-alter';

const customImage = ({ className, ...props }: MuiImageProps) => (
  <Image className="some-custom-class" {...props} />
);

You also can extend the props by importing props.

import React from 'react';
import { Image, ImageProps } from 'mui-image-alter';

type CustomImageProps = ImageProps & {
  customImage: string;
};

const customImage = ({ customImage, src, ...props }: CustomImageProps) => {
  const imageSrc = () => {
    if (customImage === 'grass') {
      return 'https//www.picture.org/grass.png';
    }

    if (customImage === 'beach') {
      return 'https//www.picture.org/beach.png';
    }

    return 'https//www.picture.org/none.png';
  };
  return <Image src={imageSrc()} {...props} />;
};

You can also change the component root element like official MUI components. Only img or img-derived component are supported from time being.

import React, { ElementType } from 'react';
import { Image, ImageProps } from 'mui-image-alter';
import NextImage from 'next/image';

type CustomImageProps = ImageProps<typeof NextImage> & {
  customImage: string;
};

const customImage = ({
  customImage,
  src,
  ...props
}: CustomImageProps) => {
  const imageSrc = () => {
    if (customImage === 'grass') {
      return 'https//www.picture.org/grass.png';
    }

    if (customImage === 'beach') {
      return 'https//www.picture.org/beach.png';
    }

    return 'https//www.picture.org/none.png';
  };
  return <Image src={imageSrc()} component={NextImage} {...props} />;
};

Like and subscribe below for more. ⏬

Props

NameTypeDefaultDescription
altstring""Alternate text for the image, which is displayed if the image fails to load or is not available. This text is also used by screen readers to provide a textual representation of the image for users who are visually impaired.
bgColorstring"inherit"Background color of the image when it first loads. This can be used to create a smooth transition between the loading state and the fully-loaded image.
classNamestring""Class name to be applied to the root element of the Image component.
distancestring / number100Distance (in any valid CSS length units) that the image should shift when it finishes loading. This prop is only used if the shift prop is set. Accept valid CSS length value.
durationnumber3000Duration of the transition (in milliseconds) when the image finishes loading. This prop is used to set the transition-duration CSS property on the image. Accept valid CSS transition-duration in milliseconds.
easingstringcubic-bezier(0.7, 0, 0.6, 1)Easing function for the transition when the image finishes loading. This prop is used to set the transition-timing-function CSS property on the image. Accept valid CSS transition-timing-function value.
errorIconboolean / nodetrueWhether or not to display an error icon when the image fails to load. If set to true, the default error icon will be displayed. If set to false, no error icon will be displayed. If set to a JSX element, the specified element will be displayed as the error icon.
fitstring"contain"How the image should be resized to fit within its container. Accept valid CSS object-fit value.
iconWrapperClassNamestring""Class name to be applied to the div element that wraps the error or loading icon. This can be used to apply custom styles to the icon using CSS.
iconWrapperStyleobject{ }Inline styles to be applied to the div element that wraps the error or loading icon.
positionstring"relative"Positioning of the image within its container. Accept valid CSS position value.
shiftboolean / stringfalseDirection in which the image should shift when it finishes loading. Possible values are "left", "right", "top", "bottom", null, or false. If set to null or false, no shift animation will be applied.
shiftDurationnumberduration * 0.3Duration of the shift animation (in milliseconds) when the image finishes loading. This prop is only used if the shift prop is set to a valid shift direction.
showLoadingboolean / nodefalseWhether or not to display a loading indicator while the image is loading. If set to true, the default loading indicator will be displayed. If set to false, no loading indicator will be displayed. If set to a JSX element, the specified element will be displayed as the loading indicator.
src *stringSource of the image to be displayed. This value should be a valid URL or file path to the image.
styleobjectInline styles to be applied to the root element of the Image component.
wrapperClassNamestring""Class name to be applied to the root div element that wraps the Image component.
wrapperStyleobjectInline styles to be applied to the root div element that wraps the Image component.
sxobjectAllows the user to style the Image component using the theme and style props provided by the MUI library. Used in the same way as the sx prop in other MUI components. Check out MUI official documentation of the sx prop.
componentstring / nodeAllows the user to specify a custom element to use as the root element for the Image component. Used in the same way as the component prop in other MUI components. Should only be used with elements that are derived from the img element.

* required prop

Any other props (eg. src, alt, onLoad) are passed directly to the root image element like img.

All the description on this table are generated using ChatGPT and edited by me. 👍

Material guidelines for loading images

✅ Fade-in

Visualize the image fading in, like a print during the photo development process.

✅ Opacity, exposure, and saturation recommendations

Images should begin loading with low contrast levels and desaturated color. Once image opacity reaches 100%, display the image with full-color saturation.

✅ Duration

A longer duration is recommended for loading images, and a shorter duration is recommended for transitions.

✅ Animation

Add a small position shift to loading images.

(Source)

Comparison with similar components

Featuremui-imagemui-image-altermaterial-ui-image
Size (minzipped)npm bundle sizenpm bundle sizenpm bundle size
Supports MUI v5
Supports MUI component prop
Built-in Typescript types
Fade-in
Progressive level adjustments
Suggested duration
Optional shift animation
Supports legacy MUI versions

Like this project?

Star this project and also the original project too if it is useful for you.

Also, consider buying me a coffee!

"Buy Me A Coffee"

License

Copyright (c) 2022 benmneb

Copyright (c) 2023 mddanish00

ISC License

Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.

Other License

The mui-image types from DefinitelyTyped project is licensed under MIT License.

This component types structure based on types of components created by Material UI under MIT License.