Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
react-medium-image-zoom
Advanced tools
The original medium.com-inspired image zooming library for React.
View the storybook examples to see various usages.
Features:
<img />
, including all object-fit
values, any object-position
,
and loading="lazy"
<div>
and <span>
with any background-image
,
background-size
,
and background-position
<picture>
with <source />
and <img />
<figure>
with <img />
<svg>
dependencies
Requirements to know about:
<dialog>
element (caniuse dialog)ResizeObserver
(caniuse ResizeObserver)ES2021
. If you need to support older environments,
run this package through your build system.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>
)
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
// Allow swipe gesture to unzoom.
// Default: true
canSwipeToUnzoom?: boolean
// 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
// Swipe gesture threshold after which to unzoom.
// Default: 10
swipeToUnzoomThreshold?: number
// 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
}
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>
)
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.
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 rem
s 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
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>
</>
}
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 nowtransitionDuration
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 removedzoomZindex
was removed, for we are using the <dialog>
element nowAnd you can now provide zoomImg
props to specify a different image to load when zooming.
Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!
5.2.12
FAQs
Accessible medium.com-style image zoom for React
The npm package react-medium-image-zoom receives a total of 103,673 weekly downloads. As such, react-medium-image-zoom popularity was classified as popular.
We found that react-medium-image-zoom demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Β It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.