import { fileURLToPath } from "node:url";
import { transformAsync } from "@babel/core";
// @ts-expect-error — no types ship with @babel/preset-react
import presetReact from "@babel/preset-react";
import { defineConfig, type Plugin } from "vite";
import solid from "vite-plugin-solid";
const demoRoot = fileURLToPath(new URL("./", import.meta.url));
const repoRoot = fileURLToPath(new URL("../", import.meta.url));
/** The Base UI (React) "ground truth" half of the side-by-side gallery. */
const REACT_DEMOS = /\/demo\/src\/react\//;
/**
* React-only JSX transform for the side-by-side demo gallery.
*
* Files under `demo/src/react/**` are the Base UI ground-truth demos; they
* compile with `@babel/preset-react` (automatic runtime). Babel only lowers
* JSX; Vite's own esbuild pass strips the remaining TypeScript afterwards.
*
* Everything else (the Quoin library + `demo/src/solid/**`) is handled by
* `vite-plugin-solid` below, configured with the SAME `babel-preset-solid`
* options the library's Bun build uses (`scripts/solid-plugin.ts`):
* `{ moduleName: "@solidjs/web", generate: "dom", hydratable: false }`.
*/
function reactJsxBabel(): Plugin {
const JSX = /\.[jt]sx(?:$|\?)/;
return {
name: "react-jsx-babel",
enforce: "pre",
async transform(code, id) {
const file = id.split("?")[0] ?? id;
if (!JSX.test(id) || !REACT_DEMOS.test(file)) return null;
const result = await transformAsync(code, {
filename: file,
configFile: false,
babelrc: false,
sourceMaps: true,
parserOpts: { plugins: ["typescript", "jsx"] },
presets: [[presetReact, { runtime: "automatic" }]],
});
if (!result?.code) return null;
return { code: result.code, map: result.map };
},
};
}
export default defineConfig({
root: demoRoot,
plugins: [
reactJsxBabel(),
solid({
// The React demos are compiled by `reactJsxBabel` above.
exclude: REACT_DEMOS,
solid: {
moduleName: "@solidjs/web",
generate: "dom",
hydratable: false,
},
}),
],
resolve: {
conditions: ["development", "browser"],
// One copy of each runtime — duplicates break reactivity / React context.
dedupe: [
"solid-js",
"@solidjs/web",
"@solidjs/signals",
"react",
"react-dom",
],
},
optimizeDeps: {
include: [
"solid-js",
"@solidjs/web",
"@solidjs/signals",
"react",
"react-dom",
"react-dom/client",
"react/jsx-runtime",
],
},
server: {
// Demos import component source from `../src`, outside the Vite root.
fs: { allow: [repoRoot] },
},
});