Skip to content

Conversation

Tsukistar
Copy link

Summary

refactor the plugin-medium-zoom  to ImgZoom in getCustomMDXComponent with React 19 Compatibility.
This PR refactors the image component implementation by:

  1. Keeping the original component Img and add a new component ImgZoom to make the image zoomable.
  2. Ensuring proper theme integration with CSS variables for background colors.
  3. Maintaining full backward compatibility while improving component modularity

The ImgZoom component maintains all previous zoom functionality using medium-zoom library, with enhanced ref forwarding capabilities and proper cleanup logic to prevent memory leaks. Both components are properly exported and registered in the MDX component map for immediate use in documentation.

To add a click-to-zoom image in MDX, use the following:
<ImgZoom src="./example.png" alt="An image that can be zoomed" />

Related Issue

close: #2325

Checklist

  • Tests updated (or not required).
  • Documentation updated (or not required).

Copy link

netlify bot commented Jul 10, 2025

Deploy Preview for rspress-v2 failed. Why did it fail? →

Name Link
🔨 Latest commit 5b5d6ba
🔍 Latest deploy log https://app.netlify.com/projects/rspress-v2/deploys/68764809774129000847946d

Copy link

netlify bot commented Jul 10, 2025

Deploy Preview for rspress failed. Why did it fail? →

Name Link
🔨 Latest commit 5b5d6ba
🔍 Latest deploy log https://app.netlify.com/projects/rspress/deploys/6876480907db120008450a91

@@ -1,6 +1,42 @@
import { normalizeImagePath } from '@rspress/runtime';
import mediumZoom from 'medium-zoom';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for your contribution,

what's the difference between 'react-medium-image-zoom' and 'medium-zoom'

Copy link
Author

@Tsukistar Tsukistar Jul 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both of them can be used to implement image zooming.

The 'medium-zoom' is the package used in @rspress/plugin-medium-zoom, it's a standalone vanilla JavaScript library and it's a lower-level, framework-agnostic JavaScript library.

The 'react-medium-image-zoom' is a React component library designed specifically for React applications. It typically wrap the element with its component, and it handles the zoom functionality, including managing its own state or allowing for controlled state management.

When I refactored this part, I considered using the existing solution within the @rspress/plugin-medium-zoom plugin. If 'react-medium-image-zoom' is a better fit for this project, I will make another commit using it.

Copy link
Member

@SoonIter SoonIter Jul 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

medium-zoom has not been maintained for a long time. so I recommend 'react-medium-image-zoom' more

BTW, there is an interesting challenge for you here, which is a bit more complex than this PR, you can continue with it.

You can try using the default value of mediumZoom config in rspress.config.ts to switch Img component to ImgZoom component by default for users

Here are some tips that you might find useful.

  1. you can pass process.env.MEDIUM_ZOOM via initRsbuild.ts source.define from compileTime to runtime

https://github.com/web-infra-dev/rspress/blob/e0b4b135218ad6065c0a1eabf9d7e63a2447f9db/packages/core/src/node/initRsbuild.ts#L226

  1. switch Img component to ImgZoom component by default

https://github.com/web-infra-dev/rspress/blob/e0b4b135218ad6065c0a1eabf9d7e63a2447f9db/packages/theme-default/src/layout/DocLayout/docComponents/index.tsx#L11

Some pseudocode

import { A } from './a';
import { Code } from './code';
import { Hr } from './hr';
import { Img, ImgZoom } from './img';
import { Li, Ol, Ul } from './list';
import { Blockquote, P, Strong } from './paragraph';
import { PreWithCodeButtonGroup } from './pre';
import { Table, Td, Th, Tr } from './table';
import { H1, H2, H3, H4, H5, H6 } from './title';

export function getCustomMDXComponent() {
  return {
    h1: H1,
    h2: H2,
    h3: H3,
    h4: H4,
    h5: H5,
    h6: H6,
    ul: Ul,
    ol: Ol,
    li: Li,
    table: Table,
    td: Td,
    th: Th,
    tr: Tr,
    hr: Hr,
    p: P,
    blockquote: Blockquote,
    strong: Strong,
    a: A,
    code: Code,
    pre: PreWithCodeButtonGroup,
    img: process.env.MEDIUM_ZOOM ? ImgZoom : Img,
  };
}
  1. remove this plugin

https://github.com/web-infra-dev/rspress/blob/e0b4b135218ad6065c0a1eabf9d7e63a2447f9db/packages/core/src/node/medium-zoom/index.ts#L6

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that possible to check the img size to determine whether the img should be considered as zoomable?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that possible to check the img size to determine whether the img should be considered as zoomable?

This seems to be a separate feature that can be implemented in other PRs.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems a little challenging. I will complete this challenge in my PR.

@SoonIter
Copy link
Member

#2165

There is an issue that is very similar to this PR, you can also try it out~

@Tsukistar
Copy link
Author

I'll try it after I finish this PR, thank you!

Tsukistar and others added 3 commits July 15, 2025 20:20
…age-zoom' and refactor configuration

- Replace 'medium-zoom' library with 'react-medium-image-zoom'
- Refactor 'mediumZoom' configuration to use process.env for conditional component selection
- Update Img/ImgZoom component mapping logic
@Tsukistar
Copy link
Author

Hi @SoonIter,

I've completed this PR following your guidance. I've replaced the medium-zoom to react-medium-image-zoom and I've replaced options with UncontrolledProps in react-medium-image-zoom. This allows users to directly pass any UncontrolledProps in react-medium-image-zoom, as the way in the medium-zoom plugin's documentation (https://github.com/web-infra-dev/rspress/blame/0c109a3b54287ea6b44b04870b229d6953765f4a/packages/document/docs/en/plugin/official-plugins/medium-zoom.mdx#L30-L35C192)

I'm considering whether process.env.MEDIUM_ZOOM_OPTIONS is the most suitable method for conveying option information. What are your thoughts on this approach?

@SoonIter
Copy link
Member

SoonIter commented Jul 16, 2025

Sorry, I made a mistake

There are two image syntaxes in md, after this change, only images with the md syntax ![]() will take effect.

We also need to use remark-image to make the images in <img src=“” /> effective...

<img src="" />

![]()

So I might pending this PR, there are still some tasks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Refactor]: refactor mediumZoom to <Img /> in getCustomMDXComponent
3 participants