Skip to content
Open
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 .changeset/violet-trees-jam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ladle/react": patch
---

Upgrade the embedded Vite dependency to Vite 8 and align the default React plugin and Node.js engine range with Vite's current requirements.
2 changes: 1 addition & 1 deletion e2e/babel/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"@ladle/playwright-config": "workspace:*",
"@ladle/react": "workspace:*",
"@playwright/test": "^1.49.1",
"@vitejs/plugin-react": "^4.3.4",
"@vitejs/plugin-react": "^6.0.2",
"cross-env": "^7.0.3",
"react": "^19.0.0",
"react-dom": "^19.0.0"
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"typescript-eslint": "^8.18.1"
},
"engines": {
"node": ">=22.0.0"
"node": ">=22.12.0"
},
"pnpm": {
"peerDependencyRules": {
Expand Down
81 changes: 46 additions & 35 deletions packages/ladle/lib/app/src/story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ const StoryFrame = ({
);
};

const StoryLoaded = ({ story }: { story: string }) => {
React.useEffect(() => {
document.documentElement.setAttribute("data-storyloaded", "");
return () => document.documentElement.removeAttribute("data-storyloaded");
}, [story]);
return null;
};

const Story = ({
globalState,
dispatch,
Expand Down Expand Up @@ -97,45 +105,48 @@ const Story = ({
return (
<ErrorBoundary>
<React.Suspense fallback={<Ring />}>
<StoryFrame
active={iframeActive}
story={globalState.story}
width={width}
mode={globalState.mode}
>
<SynchronizeHead
active={
(iframeActive || width > 0) &&
globalState.mode !== ModeState.Preview
}
rtl={globalState.rtl}
<>
<StoryFrame
active={iframeActive}
story={globalState.story}
width={width}
mode={globalState.mode}
>
<MDXProvider
components={{
code: (props) => (
<CodeHighlight
{...(props as any)}
theme={globalState.theme}
/>
),
}}
<SynchronizeHead
active={
(iframeActive || width > 0) &&
globalState.mode !== ModeState.Preview
}
rtl={globalState.rtl}
width={width}
>
<Provider
config={config}
globalState={globalState}
dispatch={dispatch}
storyMeta={storyDataMeta}
<MDXProvider
components={{
code: (props) => (
<CodeHighlight
{...(props as any)}
theme={globalState.theme}
/>
),
}}
>
{storyData ? (
React.createElement(storyData.component)
) : (
<StoryNotFound activeStory={globalState.story} />
)}
</Provider>
</MDXProvider>
</SynchronizeHead>
</StoryFrame>
<Provider
config={config}
globalState={globalState}
dispatch={dispatch}
storyMeta={storyDataMeta}
>
{storyData ? (
React.createElement(storyData.component)
) : (
<StoryNotFound activeStory={globalState.story} />
)}
</Provider>
</MDXProvider>
</SynchronizeHead>
</StoryFrame>
<StoryLoaded story={globalState.story} />
</>
</React.Suspense>
</ErrorBoundary>
);
Expand Down
21 changes: 15 additions & 6 deletions packages/ladle/lib/cli/vite-plugin/mdx-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const unknownBackticks = (code) => {
function mdxPlugin(opts) {
/** @type any */
let reactPluginTransform;
let usesReactPluginBabel;
let usesReactPluginSwc;
const isDev = opts.mode === "development";
const { process } = createFormatAwareProcessors({
Expand All @@ -65,10 +66,14 @@ function mdxPlugin(opts) {
name: "ladle:stories-mdx",
enforce: "pre",
configResolved: ({ plugins }) => {
reactPluginTransform = plugins.find(
(p) =>
p.name === "vite:react-babel" && typeof p.transform === "function",
)?.transform;
const reactPluginBabel = plugins.find(
(p) => p.name === "vite:react-babel",
);
reactPluginTransform =
typeof reactPluginBabel?.transform === "function"
? reactPluginBabel.transform
: undefined;
usesReactPluginBabel = Boolean(reactPluginBabel);
usesReactPluginSwc = plugins.some((p) => p.name === "vite:react-swc");
},
async transform(value, path) {
Expand Down Expand Up @@ -104,17 +109,21 @@ function mdxPlugin(opts) {
const filename = `${filepath}${
querystring ? "&ext=.jsx" : "?ext=.jsx"
}`;
if (!usesReactPluginSwc && !reactPluginTransform) {
if (!usesReactPluginSwc && !usesReactPluginBabel) {
throw new Error(
`You need to install and use @vitejs/plugin-react-swc or @vitejs/plugin-react so ${filename} can be compiled.`,
);
}
const transformed = await transformWithEsbuild(code, filename);
if (reactPluginTransform) {
return await reactPluginTransform(
(await transformWithEsbuild(code, filename)).code,
transformed.code,
filepath.replace(".mdx", ".jsx"),
);
}
if (usesReactPluginBabel) {
return transformed.code;
}
return { code, map: compiled.map };
}
},
Expand Down
6 changes: 1 addition & 5 deletions packages/ladle/lib/cli/vite-plugin/vite-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,8 @@ function ladlePlugin(config, configFolder, mode) {
});
}`
: "";
// make sure the `loaded` attr is set even if the story is loaded through iframe
const setLoadedAttr = `typeof window !== 'undefined' &&
window.document &&
window.document.createElement && document.documentElement.setAttribute("data-storyloaded", "");`;
return {
code: `${code}\n${setLoadedAttr}\n${invalidateHmr}\n${watcherImport}\nif (import.meta.hot) {
code: `${code}\n${invalidateHmr}\n${watcherImport}\nif (import.meta.hot) {
import.meta.hot.accept(() => {
storyUpdated();
});
Expand Down
10 changes: 5 additions & 5 deletions packages/ladle/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@
"@ladle/react-context": "^1.0.1",
"@mdx-js/mdx": "^3.1.0",
"@mdx-js/react": "^3.1.0",
"@vitejs/plugin-react": "^4.3.4",
"@vitejs/plugin-react-swc": "^3.7.2",
"@vitejs/plugin-react": "^6.0.2",
"@vitejs/plugin-react-swc": "^4.3.1",
"axe-core": "^4.10.2",
"boxen": "^8.0.1",
"chokidar": "^4.0.3",
Expand All @@ -72,7 +72,7 @@
"remark-gfm": "^4.0.0",
"source-map": "^0.7.4",
"vfile": "^6.0.3",
"vite": "^6.0.5",
"vite": "^8.0.14",
"vite-tsconfig-paths": "^5.1.4"
},
"peerDependencies": {
Expand All @@ -91,14 +91,14 @@
"@types/express": "^5.0.0",
"@types/koa": "^2.15.0",
"@types/lodash.merge": "^4.6.9",
"@types/node": "^22.10.2",
"@types/node": "^22.19.19",
"@types/ws": "^8.5.13",
"cross-env": "^7.0.3",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"vitest": "^2.1.8"
},
"engines": {
"node": ">=20.0.0"
"node": "^20.19.0 || >=22.12.0"
}
}
Loading
Loading