Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 10.0.5

- Core: Add reentry guard to focus patch - [#32655](https://github.com/storybookjs/storybook/pull/32655), thanks @ia319!
- Nextjs Vite: Update internal plugin to support `svgr` use cases - [#32957](https://github.com/storybookjs/storybook/pull/32957), thanks @yannbf!

## 10.0.4

- CLI: Fix issue with running Storybook after being initialized - [#32929](https://github.com/storybookjs/storybook/pull/32929), thanks @yannbf!
Expand Down
33 changes: 24 additions & 9 deletions code/core/src/test/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,26 +111,41 @@ const enhanceContext: LoaderFunction = async (context) => {
configurable: true,
});

let currentFocus = HTMLElement.prototype.focus;

if (!patchedFocus) {
// We need to patch the focus method of HTMLElement.prototype to make it settable.
// Testing library "setup" defines a custom focus method on HTMLElement.prototype that is not settable.
// Libraries like chakra-ui also wants to define a custom focus method on HTMLElement.prototype
// which is not settable if we don't do this.
// Related issue: https://github.com/storybookjs/storybook/issues/31243
// Must save a real, original `focus` method outside of the patch beforehand
const originalFocus = HTMLElement.prototype.focus;
let currentFocus = HTMLElement.prototype.focus;

// Use a Set to track elements that are currently undergoing a focus operation
const focusingElements = new Set<HTMLElement>();

Object.defineProperties(HTMLElement.prototype, {
focus: {
configurable: true,
set: (newFocus: () => void) => {
currentFocus = newFocus;
patchedFocus = true;
},
get: () => {
get() {
// 'this' here refers to the DOM element being operated on
if (focusingElements.has(this)) {
// Recursive call detected; to break the loop, return the original focus method.
return originalFocus;
}

// Add protection marker
focusingElements.add(this);

// Use setTimeout(..., 0) to defer the "remove marker" operation to the next event loop.
// This ensures the marker persists for the entire synchronous call chain (including all recursive calls).
setTimeout(() => focusingElements.delete(this), 0);

// Return the focus method that should currently be used
return currentFocus;
},
},
});

patchedFocus = true;
}
}
};
Expand Down
2 changes: 1 addition & 1 deletion code/frameworks/nextjs-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
"@storybook/react": "workspace:*",
"@storybook/react-vite": "workspace:*",
"styled-jsx": "5.1.6",
"vite-plugin-storybook-nextjs": "^3.0.0"
"vite-plugin-storybook-nextjs": "^3.1.0"
},
"devDependencies": {
"@types/node": "^22.0.0",
Expand Down
10 changes: 8 additions & 2 deletions code/frameworks/nextjs-vite/src/preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,16 @@ export const viteFinal: StorybookConfigVite['viteFinal'] = async (config, option
await normalizePostCssConfig(searchPath);
}

const { nextConfigPath } = await options.presets.apply<FrameworkOptions>('frameworkOptions');
const { nextConfigPath, image = {} } =
await options.presets.apply<FrameworkOptions>('frameworkOptions');

const nextDir = nextConfigPath ? dirname(nextConfigPath) : undefined;

const vitePluginOptions = {
image,
dir: nextDir,
};

return {
...reactConfig,
resolve: {
Expand All @@ -83,6 +89,6 @@ export const viteFinal: StorybookConfigVite['viteFinal'] = async (config, option
'styled-jsx/style.js': fileURLToPath(import.meta.resolve('styled-jsx/style')),
},
},
plugins: [...(reactConfig?.plugins ?? []), vitePluginStorybookNextjs({ dir: nextDir })],
plugins: [...(reactConfig?.plugins ?? []), vitePluginStorybookNextjs(vitePluginOptions)],
};
};
4 changes: 4 additions & 0 deletions code/frameworks/nextjs-vite/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ type BuilderName = CompatibleString<'@storybook/builder-vite'>;
export type FrameworkOptions = {
/** The path to the Next.js configuration file. */
nextConfigPath?: string;
image?: {
includeFiles?: string[];
excludeFiles?: string[];
};
builder?: BuilderOptions;
};

Expand Down
3 changes: 2 additions & 1 deletion code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -283,5 +283,6 @@
"Dependency Upgrades"
]
]
}
},
"deferredNextVersion": "10.0.5"
}
10 changes: 5 additions & 5 deletions code/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6553,7 +6553,7 @@ __metadata:
semver: "npm:^7.3.5"
styled-jsx: "npm:5.1.6"
typescript: "npm:^5.8.3"
vite-plugin-storybook-nextjs: "npm:^3.0.0"
vite-plugin-storybook-nextjs: "npm:^3.1.0"
peerDependencies:
next: ^14.1.0 || ^15.0.0 || ^16.0.0
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
Expand Down Expand Up @@ -26391,9 +26391,9 @@ __metadata:
languageName: node
linkType: hard

"vite-plugin-storybook-nextjs@npm:^3.0.0":
version: 3.0.0
resolution: "vite-plugin-storybook-nextjs@npm:3.0.0"
"vite-plugin-storybook-nextjs@npm:^3.1.0":
version: 3.1.0
resolution: "vite-plugin-storybook-nextjs@npm:3.1.0"
dependencies:
"@next/env": "npm:16.0.0"
image-size: "npm:^2.0.0"
Expand All @@ -26405,7 +26405,7 @@ __metadata:
next: ^14.1.0 || ^15.0.0 || ^16.0.0
storybook: ^0.0.0-0 || ^9.0.0 || ^10.0.0 || ^10.0.0-0
vite: ^5.0.0 || ^6.0.0 || ^7.0.0
checksum: 10c0/bb460ddab4d46a98bdd1525c7f18117a0a335a3500243534955532b5a209d3e63aad369a96a669618dd13b785cabe74560b4439ce063c953c51b9ab44abb7b10
checksum: 10c0/a3c87a91eca84bda3b96eb8d66afa654542ed1ee3dbd3ec1a43dace4b53611e552a44d7ba8436888e965dbc6f099ddfa9c4ab91f691a19357ddc2f2cc940f9c5
languageName: node
linkType: hard

Expand Down
2 changes: 1 addition & 1 deletion docs/versions/latest.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"version":"10.0.4","info":{"plain":"- CLI: Fix issue with running Storybook after being initialized - [#32929](https://github.com/storybookjs/storybook/pull/32929), thanks @yannbf!\n- CRA: Fix `module` not defined in ESM - [#32940](https://github.com/storybookjs/storybook/pull/32940), thanks @ndelangen!"}}
{"version":"10.0.5","info":{"plain":"- Core: Add reentry guard to focus patch - [#32655](https://github.com/storybookjs/storybook/pull/32655), thanks @ia319!\n- Nextjs Vite: Update internal plugin to support `svgr` use cases - [#32957](https://github.com/storybookjs/storybook/pull/32957), thanks @yannbf!"}}
2 changes: 1 addition & 1 deletion docs/versions/next.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"version":"10.1.0-alpha.4","info":{"plain":"- Core: Better handling for TypeScript satisfies/as syntaxes - [#32891](https://github.com/storybookjs/storybook/pull/32891), thanks @yannbf!\n- Core: Fix wrong import to fix Yarn PnP support - [#32928](https://github.com/storybookjs/storybook/pull/32928), thanks @yannbf!\n- ESlint: Update `@storybook/experimental-nextjs-vite` in `no-renderer-packages` rule - [#32909](https://github.com/storybookjs/storybook/pull/32909), thanks @ndelangen!\n- React Native: Update withStorybook setup instructions - [#32919](https://github.com/storybookjs/storybook/pull/32919), thanks @dannyhw!\n- React: Change examples to stories in manifests and show correct examples and prop types - [#32908](https://github.com/storybookjs/storybook/pull/32908), thanks @kasperpeulen!"}}
{"version":"10.1.0-alpha.5","info":{"plain":"- CLI: Fix issue with running Storybook after being initialized - [#32929](https://github.com/storybookjs/storybook/pull/32929), thanks @yannbf!\n- CRA: Fix `module` not defined in ESM - [#32940](https://github.com/storybookjs/storybook/pull/32940), thanks @ndelangen!\n- React: Improve automatic component, automatic imports, support barrel files and enhance story filtering - [#32939](https://github.com/storybookjs/storybook/pull/32939), thanks @kasperpeulen!\n- Theming: Set `themes.normal` according to user preference and export `getPreferredColorScheme` - [#28721](https://github.com/storybookjs/storybook/pull/28721), thanks @elisezhg!"}}