diff --git a/code/frameworks/nextjs/build-config.ts b/code/frameworks/nextjs/build-config.ts index e7c8f55e43c4..bcc08973d6d9 100644 --- a/code/frameworks/nextjs/build-config.ts +++ b/code/frameworks/nextjs/build-config.ts @@ -28,6 +28,10 @@ const config: BuildEntries = { exportEntries: ['./navigation.mock'], entryPoint: './src/export-mocks/navigation/index.ts', }, + { + exportEntries: ['./link.mock'], + entryPoint: './src/export-mocks/link/index.tsx', + }, { exportEntries: ['./router.mock'], entryPoint: './src/export-mocks/router/index.ts', diff --git a/code/frameworks/nextjs/package.json b/code/frameworks/nextjs/package.json index 488eec1df0e2..2e92cca7391d 100644 --- a/code/frameworks/nextjs/package.json +++ b/code/frameworks/nextjs/package.json @@ -47,6 +47,11 @@ "./image-context": "./dist/image-context.js", "./images/next-image": "./dist/images/next-image.js", "./images/next-legacy-image": "./dist/images/next-legacy-image.js", + "./link.mock": { + "types": "./dist/export-mocks/link/index.d.ts", + "code": "./src/export-mocks/link/index.tsx", + "default": "./dist/export-mocks/link/index.js" + }, "./navigation.mock": { "types": "./dist/export-mocks/navigation/index.d.ts", "code": "./src/export-mocks/navigation/index.ts", diff --git a/code/frameworks/nextjs/src/export-mocks/link/index.tsx b/code/frameworks/nextjs/src/export-mocks/link/index.tsx new file mode 100644 index 000000000000..2237a67f7cc6 --- /dev/null +++ b/code/frameworks/nextjs/src/export-mocks/link/index.tsx @@ -0,0 +1,45 @@ +import React from 'react'; + +import { fn } from 'storybook/test'; + +const linkAction = fn().mockName('next/link::Link'); + +const MockLink = React.forwardRef(function MockLink( + { + href, + as: _as, + replace, + scroll, + shallow, + prefetch, + passHref, + legacyBehavior, + locale, + onClick, + children, + ...rest + }, + ref +) { + const hrefString = + typeof href === 'object' + ? `${href.pathname || ''}${href.query ? '?' + new URLSearchParams(href.query).toString() : ''}${href.hash || ''}` + : href; + + const handleClick = (e: React.MouseEvent) => { + e.preventDefault(); + onClick?.(e); + linkAction(hrefString, { replace, scroll, shallow, prefetch, locale }); + }; + + return ( + + {children} + + ); +}); + +MockLink.displayName = 'NextLink'; + +export default MockLink; +export { MockLink as Link }; diff --git a/code/frameworks/nextjs/src/export-mocks/webpack.ts b/code/frameworks/nextjs/src/export-mocks/webpack.ts index b5a813535737..9daaecee3a76 100644 --- a/code/frameworks/nextjs/src/export-mocks/webpack.ts +++ b/code/frameworks/nextjs/src/export-mocks/webpack.ts @@ -7,6 +7,7 @@ const mapping = { 'next/navigation': '@storybook/nextjs/navigation.mock', 'next/router': '@storybook/nextjs/router.mock', 'next/cache': '@storybook/nextjs/cache.mock', + 'next/link': '@storybook/nextjs/link.mock', ...getCompatibilityAliases(), };