diff --git a/packages/core/src/node/PluginDriver.ts b/packages/core/src/node/PluginDriver.ts index ec07a2cd0..1e007a3f6 100644 --- a/packages/core/src/node/PluginDriver.ts +++ b/packages/core/src/node/PluginDriver.ts @@ -46,19 +46,10 @@ export class PluginDriver { const enableLastUpdated = themeConfig?.lastUpdated || themeConfig?.locales?.some(locale => locale.lastUpdated); - const mediumZoomConfig = config?.mediumZoom ?? true; if (enableLastUpdated) { const { pluginLastUpdated } = await import('./last-updated/index'); this.addPlugin(pluginLastUpdated()); } - if (mediumZoomConfig) { - const { pluginMediumZoom } = await import('./medium-zoom/index'); - this.addPlugin( - pluginMediumZoom( - typeof mediumZoomConfig === 'object' ? mediumZoomConfig : undefined, - ), - ); - } (config.plugins || []).forEach(plugin => { this.addPlugin(plugin); diff --git a/packages/core/src/node/initRsbuild.ts b/packages/core/src/node/initRsbuild.ts index fc09c58d1..1cbf558dc 100644 --- a/packages/core/src/node/initRsbuild.ts +++ b/packages/core/src/node/initRsbuild.ts @@ -228,6 +228,14 @@ async function createInternalBuildConfig( 'process.env.RSPRESS_SOCIAL_ICONS': JSON.stringify( getSocialIcons(config.themeConfig?.socialLinks), ), + 'process.env.MEDIUM_ZOOM': + typeof config.mediumZoom === 'object' + ? config.mediumZoom.isZoom + : !!config.mediumZoom, + 'process.env.MEDIUM_ZOOM_OPTIONS': + typeof config.mediumZoom === 'object' + ? JSON.stringify(config.mediumZoom.options) + : '', }, }, performance: { diff --git a/packages/shared/package.json b/packages/shared/package.json index edde3e088..f335e078a 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -41,6 +41,7 @@ "@shikijs/rehype": "^3.4.2", "gray-matter": "4.0.3", "lodash-es": "^4.17.21", + "react-medium-image-zoom": "^5.2.14", "unified": "^11.0.5" }, "devDependencies": { diff --git a/packages/shared/src/types/index.ts b/packages/shared/src/types/index.ts index e03bb56b9..0624f3e31 100644 --- a/packages/shared/src/types/index.ts +++ b/packages/shared/src/types/index.ts @@ -1,7 +1,7 @@ import type { RsbuildConfig } from '@rsbuild/core'; import type { loadConfig } from '@rsbuild/core'; import type { RehypeShikiOptions } from '@shikijs/rehype'; -import type { ZoomOptions } from 'medium-zoom'; +import type { UncontrolledProps } from 'react-medium-image-zoom'; import type { PluggableList } from 'unified'; import type { AdditionalPage, RspressPlugin } from './Plugin'; import type { @@ -162,8 +162,8 @@ export interface UserConfig { mediumZoom?: | boolean | { - selector?: string; - options?: ZoomOptions; + isZoom: boolean; + options?: UncontrolledProps; }; /** * Multi version config diff --git a/packages/theme-default/package.json b/packages/theme-default/package.json index b81b292f8..27573c689 100644 --- a/packages/theme-default/package.json +++ b/packages/theme-default/package.json @@ -50,6 +50,7 @@ "nprogress": "^0.2.0", "react": "^19.1.0", "react-dom": "^19.1.0", + "react-medium-image-zoom": "^5.2.14", "shiki": "^3.4.2" }, "devDependencies": { diff --git a/packages/theme-default/src/layout/DocLayout/docComponents/img.tsx b/packages/theme-default/src/layout/DocLayout/docComponents/img.tsx index 0e547192b..8bbbb8f51 100644 --- a/packages/theme-default/src/layout/DocLayout/docComponents/img.tsx +++ b/packages/theme-default/src/layout/DocLayout/docComponents/img.tsx @@ -1,6 +1,18 @@ import { normalizeImagePath } from '@rspress/runtime'; +import Zoom from 'react-medium-image-zoom'; +import 'react-medium-image-zoom/dist/styles.css'; import type { ComponentProps } from 'react'; export const Img = (props: ComponentProps<'img'>) => { return ; }; + +const ImgZoomProps = JSON.parse(process.env.MEDIUM_ZOOM_OPTIONS || ''); + +export const ImgZoom = (props: ComponentProps<'img'>) => { + return ( + + + + ); +}; diff --git a/packages/theme-default/src/layout/DocLayout/docComponents/index.tsx b/packages/theme-default/src/layout/DocLayout/docComponents/index.tsx index 82f8bcf23..3e79cb381 100644 --- a/packages/theme-default/src/layout/DocLayout/docComponents/index.tsx +++ b/packages/theme-default/src/layout/DocLayout/docComponents/index.tsx @@ -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'; @@ -30,6 +30,6 @@ export function getCustomMDXComponent() { a: A, code: Code, pre: PreWithCodeButtonGroup, - img: Img, + img: process.env.MEDIUM_ZOOM ? ImgZoom : Img, }; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5930a2b90..2d3702c08 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1503,6 +1503,9 @@ importers: lodash-es: specifier: ^4.17.21 version: 4.17.21 + react-medium-image-zoom: + specifier: ^5.2.14 + version: 5.2.14(react-dom@19.1.0(react@19.1.0))(react@19.1.0) unified: specifier: ^11.0.5 version: 11.0.5 @@ -1579,6 +1582,9 @@ importers: react-dom: specifier: ^19.1.0 version: 19.1.0(react@19.1.0) + react-medium-image-zoom: + specifier: ^5.2.14 + version: 5.2.14(react-dom@19.1.0(react@19.1.0))(react@19.1.0) shiki: specifier: ^3.4.2 version: 3.4.2 @@ -5668,6 +5674,12 @@ packages: '@types/react': '>=18' react: '>=18' + react-medium-image-zoom@5.2.14: + resolution: {integrity: sha512-nfTVYcAUnBzXQpPDcZL+cG/e6UceYUIG+zDcnemL7jtAqbJjVVkA85RgneGtJeni12dTyiRPZVM6Szkmwd/o8w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-refresh@0.17.0: resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} engines: {node: '>=0.10.0'} @@ -11672,6 +11684,11 @@ snapshots: transitivePeerDependencies: - supports-color + react-medium-image-zoom@5.2.14(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-refresh@0.17.0: {} react-router-dom@6.29.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0):