Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/theme-default/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"github-slugger": "^2.0.0",
"hast-util-to-jsx-runtime": "^2.3.6",
"lodash-es": "^4.17.21",
"medium-zoom": "1.1.0",
"nprogress": "^0.2.0",
"react": "^19.1.0",
"react-dom": "^19.1.0",
Expand Down
36 changes: 36 additions & 0 deletions packages/theme-default/src/layout/DocLayout/docComponents/img.tsx
Original file line number Diff line number Diff line change
@@ -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.

import type React from 'react';
import type { ComponentProps } from 'react';
import { useCallback, useEffect, useRef } from 'react';

export const Img = (props: ComponentProps<'img'>) => {
return <img {...props} src={normalizeImagePath(props.src || '')} />;
};

export const ImgZoom = ({
ref: refProp,
...props
}: ComponentProps<'img'> & { ref?: React.Ref<HTMLImageElement> }) => {
const imgRef = useRef<HTMLImageElement>(null);
const combinedRef = useCallback(
(node: HTMLImageElement) => {
if (refProp) {
if (typeof refProp === 'function') {
refProp(node);
} else {
refProp.current = node;
}
}
imgRef.current = node;
},
[refProp],
);

useEffect(() => {
if (!imgRef.current) return;
const zoom = mediumZoom(imgRef.current, {
background: 'var(--rp-c-bg)',
});

return () => {
zoom.detach();
};
}, []);

return <img ref={combinedRef} {...props} />;
};
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@
}
}

.medium-zoom-overlay,
.medium-zoom-image--opened {
z-index: 999;
}

:global(.header-anchor) {
color: var(--rp-c-brand);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { A } from './a';
import { Code } from './code';
import { Hr } from './hr';
import { Img } from './img';
import { Img, ImgZoom } from './img';
import { Li, Ol, Ul } from './list';
import { Blockquote, P, Strong } from './paragraph';
import { PreWithCodeButtonGroup } from './pre';
Expand Down Expand Up @@ -31,5 +31,6 @@ export function getCustomMDXComponent() {
code: Code,
pre: PreWithCodeButtonGroup,
img: Img,
imgZoom: ImgZoom,
};
}
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.