Skip to content

Commit

Permalink
Merge branch 'next' into bugfix/nextjs-image-context-2
Browse files Browse the repository at this point in the history
  • Loading branch information
ndelangen committed Sep 20, 2023
2 parents f513671 + 64d4536 commit 2382868
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 27 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 7.4.3

- CLI: Fix `sb add` adding duplicative entries - [#24229](https://github.com/storybookjs/storybook/pull/24229), thanks [@ndelangen](https://github.com/ndelangen)!
- NextJS: Add compatibility with nextjs `13.5` - [#24239](https://github.com/storybookjs/storybook/pull/24239), thanks [@ndelangen](https://github.com/ndelangen)!
- NextJS: Aliases `react` and `react-dom` like `next.js` does - [#23671](https://github.com/storybookjs/storybook/pull/23671), thanks [@sookmax](https://github.com/sookmax)!
- Types: Allow `null` in value of `experimental_updateStatus` to clear status - [#24206](https://github.com/storybookjs/storybook/pull/24206), thanks [@ndelangen](https://github.com/ndelangen)!

## 7.4.2

- Addon API: Improve the updateStatus API - [#24007](https://github.com/storybookjs/storybook/pull/24007), thanks [@ndelangen](https://github.com/ndelangen)!
Expand Down
16 changes: 14 additions & 2 deletions code/frameworks/nextjs/src/config/webpack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ import type { NextConfig } from 'next';
import { DefinePlugin } from 'webpack';
import { addScopedAlias, getNextjsVersion, resolveNextConfig } from '../utils';

const tryResolve = (path: string) => {
try {
return require.resolve(path);
} catch (err) {
return false;
}
};

export const configureConfig = async ({
baseConfig,
nextConfigPath,
Expand All @@ -17,8 +25,12 @@ export const configureConfig = async ({
const nextConfig = await resolveNextConfig({ baseConfig, nextConfigPath, configDir });

addScopedAlias(baseConfig, 'next/config');
addScopedAlias(baseConfig, 'react', 'next/dist/compiled/react');
addScopedAlias(baseConfig, 'react-dom', 'next/dist/compiled/react-dom');
if (tryResolve('next/dist/compiled/react')) {
addScopedAlias(baseConfig, 'react', 'next/dist/compiled/react');
}
if (tryResolve('next/dist/compiled/react-dom')) {
addScopedAlias(baseConfig, 'react-dom', 'next/dist/compiled/react-dom');
}
setupRuntimeConfig(baseConfig, nextConfig);

return nextConfig;
Expand Down
36 changes: 36 additions & 0 deletions code/frameworks/nextjs/src/dependency-map.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { Configuration as WebpackConfig } from 'webpack';
import semver from 'semver';
import { getNextjsVersion, addScopedAlias } from './utils';

const mapping: Record<string, Record<string, string>> = {
'<11.1.0': {
'next/dist/next-server/lib/router-context': 'next/dist/next-server/lib/router-context',
},
'>=11.1.0': {
'next/dist/shared/lib/router-context': 'next/dist/shared/lib/router-context',
},
'>=13.5.0': {
'next/dist/shared/lib/router-context': 'next/dist/shared/lib/router-context.shared-runtime',
'next/dist/shared/lib/head-manager-context':
'next/dist/shared/lib/head-manager-context.shared-runtime',
'next/dist/shared/lib/app-router-context':
'next/dist/shared/lib/app-router-context.shared-runtime',
'next/dist/shared/lib/hooks-client-context':
'next/dist/shared/lib/hooks-client-context.shared-runtime',
},
};

export const configureAliasing = (baseConfig: WebpackConfig): void => {
const version = getNextjsVersion();
const result: Record<string, string> = {};

Object.keys(mapping).forEach((key) => {
if (semver.intersects(version, key)) {
Object.assign(result, mapping[key]);
}
});

Object.entries(result).forEach(([name, alias]) => {
addScopedAlias(baseConfig, name, alias);
});
};
4 changes: 2 additions & 2 deletions code/frameworks/nextjs/src/preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { getProjectRoot } from '@storybook/core-common';
import { configureConfig } from './config/webpack';
import { configureCss } from './css/webpack';
import { configureImports } from './imports/webpack';
import { configureRouting } from './routing/webpack';
import { configureStyledJsx } from './styledJsx/webpack';
import { configureImages } from './images/webpack';
import { configureRuntimeNextjsVersionResolution } from './utils';
Expand All @@ -17,6 +16,7 @@ import TransformFontImports from './font/babel';
import { configureNextFont } from './font/webpack/configureNextFont';
import nextBabelPreset from './babel/preset';
import { configureNodePolyfills } from './nodePolyfills/webpack';
import { configureAliasing } from './dependency-map';

export const addons: PresetProperty<'addons', StorybookConfig> = [
dirname(require.resolve(join('@storybook/preset-react-webpack', 'package.json'))),
Expand Down Expand Up @@ -143,13 +143,13 @@ export const webpackFinal: StorybookConfig['webpackFinal'] = async (baseConfig,
configDir: options.configDir,
});

configureAliasing(baseConfig);
configureNextFont(baseConfig);
configureNextImport(baseConfig);
configureRuntimeNextjsVersionResolution(baseConfig);
configureImports({ baseConfig, configDir: options.configDir });
configureCss(baseConfig, nextConfig);
configureImages(baseConfig, nextConfig);
configureRouting(baseConfig);
configureStyledJsx(baseConfig);
configureNodePolyfills(baseConfig);

Expand Down
18 changes: 0 additions & 18 deletions code/frameworks/nextjs/src/routing/webpack.tsx

This file was deleted.

28 changes: 26 additions & 2 deletions code/lib/cli/src/add.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { getStorybookInfo } from '@storybook/core-common';
import { getStorybookInfo, serverRequire } from '@storybook/core-common';
import { readConfig, writeConfig } from '@storybook/csf-tools';
import { isAbsolute, join } from 'path';
import SemVer from 'semver';
import dedent from 'ts-dedent';

import {
JsPackageManagerFactory,
Expand Down Expand Up @@ -38,6 +40,21 @@ const getVersionSpecifier = (addon: string) => {
return groups ? [groups[1], groups[2]] : [addon, undefined];
};

const requireMain = (configDir: string) => {
const absoluteConfigDir = isAbsolute(configDir) ? configDir : join(process.cwd(), configDir);
const mainFile = join(absoluteConfigDir, 'main');

return serverRequire(mainFile) ?? {};
};

const checkInstalled = (addonName: string, main: any) => {
const existingAddon = main.addons?.find((entry: string | { name: string }) => {
const name = typeof entry === 'string' ? entry : entry.name;
return name?.endsWith(addonName);
});
return !!existingAddon;
};

/**
* Install the given addon package and add it to main.js
*
Expand All @@ -60,9 +77,16 @@ export async function add(
}
const packageManager = JsPackageManagerFactory.getPackageManager({ force: pkgMgr });
const packageJson = await packageManager.retrievePackageJson();
const { mainConfig, configDir } = getStorybookInfo(packageJson);

if (checkInstalled(addon, requireMain(configDir))) {
throw new Error(dedent`
Addon ${addon} is already installed; we skipped adding it to your ${mainConfig}.
`);
}

const [addonName, versionSpecifier] = getVersionSpecifier(addon);

const { mainConfig } = getStorybookInfo(packageJson);
if (!mainConfig) {
logger.error('Unable to find storybook main.js config');
return;
Expand Down
2 changes: 1 addition & 1 deletion code/lib/core-common/src/utils/get-storybook-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ const getConfigInfo = (packageJson: PackageJson, configDir?: string) => {
}

return {
configDir,
configDir: storybookConfigDir,
mainConfig: findConfigFile('main', storybookConfigDir),
previewConfig: findConfigFile('preview', storybookConfigDir),
managerConfig: findConfigFile('manager', storybookConfigDir),
Expand Down
17 changes: 16 additions & 1 deletion code/lib/preview-api/src/modules/preview-web/PreviewWeb.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3502,6 +3502,19 @@ describe('PreviewWeb', () => {
document.location.search = '?id=component-one--docs&viewMode=docs';
const preview = await createAndRenderPreview();

preview.onKeydown({
composedPath: jest
.fn()
.mockReturnValue([{ tagName: 'div', getAttribute: jest.fn().mockReturnValue(null) }]),
} as any);

expect(mockChannel.emit).toHaveBeenCalledWith(PREVIEW_KEYDOWN, expect.objectContaining({}));
});

it('emits PREVIEW_KEYDOWN for regular elements, fallback to event.target', async () => {
document.location.search = '?id=component-one--docs&viewMode=docs';
const preview = await createAndRenderPreview();

preview.onKeydown({
target: { tagName: 'div', getAttribute: jest.fn().mockReturnValue(null) },
} as any);
Expand All @@ -3514,7 +3527,9 @@ describe('PreviewWeb', () => {
const preview = await createAndRenderPreview();

preview.onKeydown({
target: { tagName: 'input', getAttribute: jest.fn().mockReturnValue(null) },
composedPath: jest
.fn()
.mockReturnValue([{ tagName: 'input', getAttribute: jest.fn().mockReturnValue(null) }]),
} as any);

expect(mockChannel.emit).not.toHaveBeenCalledWith(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import type { StorySpecifier } from '../store/StoryIndexStore';
const globalWindow = globalThis;

function focusInInput(event: Event) {
const target = event.target as Element;
const target = ((event.composedPath && event.composedPath()[0]) || event.target) as Element;
return /input|textarea/i.test(target.tagName) || target.getAttribute('contenteditable') !== null;
}

Expand Down

0 comments on commit 2382868

Please sign in to comment.