react-medium-image-zoom
    TypeScript icon, indicating that this package has built-in type declarations

    5.1.2 • Public • Published

    react-medium-image-zoom

    npm version bundlephobia size npm downloads All Contributors

    The original medium.com-inspired image zooming library for React.

    Features:

    View the storybook examples to see various usages. NOTE: Help is wanted with making the examples more informative, so please start a discussion if you're able to help!

    Quickstart

    npm install --save react-medium-image-zoom
    import React from 'react'
    import Zoom from 'react-medium-image-zoom'
    import 'react-medium-image-zoom/dist/styles.css'
    
    export const MyImg = () => (
      <Zoom>
        <img
          alt="That Wanaka Tree, New Zealand by Laura Smetsers"
          src="/path/to/thatwanakatree.jpg"
          width="500"
        />
      </Zoom>
    )

    This library's compilation target is ES2021. If you find you need to support older environments, run this project through your build system.

    API

    You can pass these options to either the Uncontrolled (default) or Controlled components.

    export interface UncontrolledProps {
      // Accessible label text for when you want to unzoom
      // Default: 'Minimize image'
      a11yNameButtonUnzoom?: string
    
      // Accessible label text for when you want to zoom
      // Default: 'Expand image'
      a11yNameButtonZoom?: string
    
      // Your image (required)
      children: ReactNode
    
      // Custom CSS className to add to the zoomed <dialog>
      classDialog?: string
    
      // Provide your own unzoom button icon
      // Default: ICompress
      IconUnzoom?: ElementType
    
      // Provide your own zoom button icon
      // Default: IEnlarge
      IconZoom?: ElementType
    
      // Specify what type of element should be used for
      // internal component usage. This is useful if the
      // image is inside a <p> or <button>, for example.
      // Default: 'div'
      wrapElement?: 'div' | 'span'
    
      // Provide your own custom modal content component
      ZoomContent?: (props: {
        img: ReactElement | null;
        buttonUnzoom: ReactElement<HTMLButtonElement>;
        onUnzoom: () => void;
      }) => ReactElement;
    
      // Higher quality image attributes to use on zoom
      zoomImg?: ImgHTMLAttributes<HTMLImageElement>
    
      // Offset in pixels the zoomed image should
      // be from the window's boundaries
      // Default: 0
      zoomMargin?: number
    }

    You can pass these options to only the Controlled component.

    export interface ControlledProps {
      // ...same as UncontrolledProps
    
      // Tell the component whether or not it should be zoomed
      // Default: false
      isZoomed: boolean
    
      // Listen for hints from the component about when you
      // should zoom (`true` value) or unzoom (`false` value)
      onZoomChange?: (value: boolean) => void
    }

    Basic Usage

    Uncontrolled component (default)

    Import the component and the CSS, wrap your image with the component, and the component will handle it's own state.

    import React from 'react'
    import Zoom from 'react-medium-image-zoom'
    import 'react-medium-image-zoom/dist/styles.css'
    
    // <img />
    export const MyImg = () => (
      <Zoom>
        <img
          alt="That Wanaka Tree, New Zealand by Laura Smetsers"
          src="/path/to/thatwanakatree.jpg"
          width="500"
        />
      </Zoom>
    )
    
    // <div>
    export const MyDiv = () => (
      <Zoom>
        <div
          aria-label="That Wanaka Tree, New Zealand by Laura Smetsers"
          role="img"
          style={{
            backgroundColor: '#fff',
            backgroundImage: `url("/path/to/thatwanakatree.jpg")`,
            backgroundPosition: '50%',
            backgroundRepeat: 'no-repeat',
            backgroundSize: 'cover',
            height: '0',
            paddingBottom: '56%',
            width: '100%',
          }}
        />
      </Zoom>
    )
    
    // <picture>
    export const MyPicture = () => (
      <Zoom>
        <picture>
          <source media="(max-width: 800px)" srcSet="/path/to/teAraiPoint.jpg" />
          <img
            alt="A beautiful, serene setting in nature"
            src="/path/to/thatwanakatree.jpg"
            width="500"
          />
        </picture>
      </Zoom>
    )
    
    // <figure>
    export const MyFigure = () => (
      <figure>
        <Zoom>
          <img
            alt="That Wanaka Tree, New Zealand by Laura Smetsers"
            src="/path/to/thatwanakatree.jpg"
            width="500"
          />
        </Zoom>
        <figcaption>Photo by Laura Smetsers</figcaption>
      </figure>
    )

    Controlled component

    Import the Controlled component and the CSS, wrap your image with the component, and then dictate the isZoomed state to the component.

    import React, { useCallback, useState } from 'react'
    import { Controlled as ControlledZoom } from 'react-medium-image-zoom'
    import 'react-medium-image-zoom/dist/styles.css'
    
    const MyComponent = () => {
      const [isZoomed, setIsZoomed] = useState(false)
    
      const handleZoomChange = useCallback(shouldZoom => {
        setIsZoomed(shouldZoom)
      }, [])
    
      return (
        <ControlledZoom isZoomed={isZoomed} onZoomChange={handleZoomChange}>
          <img
            alt="That wanaka tree, alone in the water near mountains"
            src="/path/to/thatwanakatree.jpg"
            width="500"
          />
        </ControlledZoom>
      )
    )
    
    export default MyComponent

    The onZoomChange prop accepts a callback that will receive true or false based on events that occur (like click or scroll events) to assist you in determining when to zoom and unzoom the component.

    Styles

    You can import the default styles from react-medium-image-zoom/dist/styles.css and override the values from your code, or you can copy the styles.css file and alter it to your liking. The latter is the best option, given rems should be used instead of px to account for different default browser font sizes, and it's hard for a library to guess at what these values should be.

    An example of customizing the transition duration, timing function, overlay background color, and unzoom button styles with :focus-visible can be found in this story: https://rpearce.github.io/react-medium-image-zoom/?path=/story/img--custom-modal-styles

    Custom zoom modal content

    If you want to customize the zoomed modal experience with a caption, form, or other set of components, you can do so by providing a custom component to the ZoomContent prop.

    View the live example of custom zoom modal content.

    Below is some example code that demonstrates how to use this feature.

    export const MyImg = () => (
      <Zoom ZoomContent={CustomZoomContent}>
        <img
          alt="That Wanaka Tree, New Zealand by Laura Smetsers"
          src="/path/to/thatwanakatree.jpg"
          width="500"
        />
      </Zoom>
    )
    
    const CustomZoomContent = ({
      buttonUnzoom, // default unzoom button
      modalState,   // current state of the zoom modal: UNLOADED, LOADING, LOADED, UNLOADING
      img,          // your image, prepped for zooming
      //onUnzoom,   // unused here, but a callback to manually unzoom the image and
                    //   close the modal if you want to use your own buttons or
                    //   listeners in your custom experience
    }) => {
      const [isLoaded, setIsLoaded] = useState(false)
    
      useLayoutEffect(() => {
        if (modalState === 'LOADED') {
          setIsLoaded(true)
        } else if (modalState === 'UNLOADING') {
          setIsLoaded(false)
        }
      }, [modalState])
    
      const classCaption = isLoaded
        ? 'zoom-caption zoom-caption--loaded'
        : 'zoom-caption'
    
      return <>
        {buttonUnzoom}
    
        <figure>
          {img}
          <figcaption className={classCaption}>
            That Wanaka Tree, also known as the Wanaka Willow, is a willow tree
            located at the southern end of Lake Wānaka in the Otago region of New
            Zealand.
            <cite className="zoom-caption-cite">
              Wikipedia, <a className="zoom-caption-link" href="https://en.wikipedia.org/wiki/That_Wanaka_Tree">
                That Wanaka Tree
              </a>
            </cite>
          </figcaption>
        </figure>
      <>
    }

    Migrating From v4 to v5

    Here are the prop changes from v4 to be aware of:

    • closeText was renamed to a11yNameButtonUnzoom
    • openText was renamed to a11yNameButtonZoom
    • overlayBgColorStart was removed and is now controlled via the CSS selector [data-rmiz-modal-overlay="hidden"]
    • overlayBgColorEnd was removed and is now controlled via the CSS selector [data-rmiz-modal-overlay="visible"]
    • portalEl was removed, for we are using the <dialog> element now
    • transitionDuration was removed and is now controlled via the CSS selectors [data-rmiz-modal-overlay] and [data-rmiz-modal-img]
    • wrapElement was removed then added back in v5.1.0
    • wrapStyle was removed
    • zoomZindex was removed, for we are using the <dialog> element now

    And you can now provide zoomImg props to specify a different image to load when zooming.

    Contributors

    Thanks goes to these wonderful people (emoji key):

    Robert Pearce
    Robert Pearce

    💻 💬 ⚠️ 🐛 💡 🎨 👀 🤔 📖
    Cameron Bothner
    Cameron Bothner

    💻 📖 🐛 💡 🤔 👀 ⚠️
    Jeremy Bini
    Jeremy Bini

    💻 🐛
    ismay
    ismay

    🐛 🤔
    Rajit Singh
    Rajit Singh

    🐛
    Roberto Saccon
    Roberto Saccon

    🐛
    wtfdaemon
    wtfdaemon

    🐛
    Josh Sloat
    Josh Sloat

    🐛 💻 💡 👀 🤔 📖 🎨 💬
    Aswin
    Aswin

    💬
    Alex Shelkovskiy
    Alex Shelkovskiy

    🐛
    Adrian Bindiu
    Adrian Bindiu

    🐛
    Kendall Buchanan
    Kendall Buchanan

    🐛
    Kaycee
    Kaycee

    💻
    Anuj
    Anuj

    🐛 💬
    Ludwig Frank
    Ludwig Frank

    🐛 💻
    LX
    LX

    🐛 🤔
    Rosen Tomov
    Rosen Tomov

    🐛
    Tom Moor
    Tom Moor

    💻 🐛
    Johan Preynat
    Johan Preynat

    💻 🐛
    Rahul Gaba
    Rahul Gaba

    💻 🐛
    Spencer Davis
    Spencer Davis

    💻 🤔 👀 🎨
    dnlnvl
    dnlnvl

    💻
    Madi
    Madi

    🤔
    Ben Hood
    Ben Hood

    🤔 🐛 💡 👀
    Navilan
    Navilan

    🤔
    13806
    13806

    🐛
    Akshay Kadam (A2K)
    Akshay Kadam (A2K)

    🐛 🤔
    Jake Stewart
    Jake Stewart

    🐛 🤔
    hhh
    hhh

    🐛
    @davalapar
    @davalapar

    🐛
    Sun Knudsen
    Sun Knudsen

    💻 🐛 🤔 💡 💬 👀 ⚠️ 📖
    Douglas Galdino
    Douglas Galdino

    💻 📖 🐛 🤔 💡 👀 ⚠️
    Mohammed Faragallah
    Mohammed Faragallah

    🐛 🤔 💡
    Youngrok Kim
    Youngrok Kim

    💻 🐛
    Nandhagopal Ezhilmaran
    Nandhagopal Ezhilmaran

    🐛
    Mattia Astorino
    Mattia Astorino

    🐛
    Dan Wood
    Dan Wood

    📖
    Zachery C Gentry
    Zachery C Gentry

    🐛
    xmflsct
    xmflsct

    🐛
    Will.iam
    Will.iam

    💻 ⚠️
    Gourav Goyal
    Gourav Goyal

    📖
    Joshua Chen
    Joshua Chen

    🐛 💻
    David Edler
    David Edler

    🐛
    rikusen0335
    rikusen0335

    🤔
    Surjith S M
    Surjith S M

    🤔
    developergunny
    developergunny

    🐛
    Khan Mohsin
    Khan Mohsin

    💬
    Robin Goudeketting
    Robin Goudeketting

    🐛
    Botros Toro
    Botros Toro

    🤔
    Christian Guevara
    Christian Guevara

    💬
    Johan Book
    Johan Book

    🐛
    Paolo Di Bello
    Paolo Di Bello

    🤔
    Tommaso De Rossi
    Tommaso De Rossi

    📖 🐛
    Lezan
    Lezan

    🐛 🤔
    Ibrahim H. Sluma
    Ibrahim H. Sluma

    🐛
    Ben Gotow
    Ben Gotow

    🐛
    Rubon72
    Rubon72

    🐛
    wanderingme
    wanderingme

    🐛
    Thomas Strobl
    Thomas Strobl

    🐛 🤔 💡 💬 👀
    Songkeys
    Songkeys

    🐛 🤔 💡 💬 👀
    AntoineS92
    AntoineS92

    🐛
    Sindre Aubert
    Sindre Aubert

    🐛
    mx
    mx

    🐛
    Sander Heling
    Sander Heling

    🐛

    This project follows the all-contributors specification. Contributions of any kind welcome!

    Install

    npm i react-medium-image-zoom

    DownloadsWeekly Downloads

    49,109

    Version

    5.1.2

    License

    BSD-3-Clause

    Unpacked Size

    76.9 kB

    Total Files

    6

    Last publish

    Collaborators

    • rpearce