podman-desktop/storybook/vite.config.js
Václav Vančura 7259f66339
feat(storybook): auto-regenerate themes.css on color-registry changes (#16919)
* feat(storybook): auto-regenerate themes.css on color-registry changes

Add a Vite plugin that watches `color-registry.ts` and
`tailwind-color-palette.json`, then re-runs `storybook:css` and
triggers a full reload.

Also pass explicit svelte config path and watch UI package dist for
changes.

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Vaclav Vancura <[email protected]>

* fix(storybook): queue file changes during in-flight theme regeneration

Previously, saves that arrived while storybook:css was already
running were silently dropped. Now a queued flag is set and a
second regeneration runs after the first completes, so
back-to-back edits are never lost.

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Vaclav Vancura <[email protected]>

* fix(storybook): use node: prefix for Node.js built-in imports

Signed-off-by: Vaclav Vancura <[email protected]>

---------

Signed-off-by: Vaclav Vancura <[email protected]>
Co-authored-by: Claude <[email protected]>
2026-04-17 14:27:59 +02:00

142 lines
4 KiB
JavaScript

/**********************************************************************
* Copyright (C) 2024-2025 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
***********************************************************************/
/* eslint-env node */
import { join } from 'node:path';
import * as path from 'node:path';
import { svelte } from '@sveltejs/vite-plugin-svelte';
import { svelteTesting } from '@testing-library/svelte/vite';
import tailwindcss from '@tailwindcss/vite';
import { exec } from 'node:child_process';
import { promisify } from 'node:util';
import chokidar from 'chokidar';
import { defineConfig } from 'vite';
import { fileURLToPath } from 'node:url';
const execAsync = promisify(exec);
let filename = fileURLToPath(import.meta.url);
const PACKAGE_ROOT = path.dirname(filename);
const ROOT_DIR = path.join(PACKAGE_ROOT, '..');
// Vite plugin to watch color-registry and regenerate themes.css
function colorRegistryWatcher() {
let isRegenerating = false;
let queuedRegeneration = false;
async function regenerate(server) {
try {
await execAsync('pnpm run storybook:css', { cwd: ROOT_DIR });
console.log('[color-registry-watcher] themes.css regenerated successfully\n');
server.ws.send({
type: 'full-reload',
path: '*',
});
} catch (error) {
console.error('[color-registry-watcher] Failed to regenerate themes.css:', error.message);
}
}
return {
name: 'color-registry-watcher',
configureServer(server) {
const filesToWatch = [
path.join(ROOT_DIR, 'packages/main/src/plugin/color-registry.ts'),
path.join(ROOT_DIR, 'tailwind-color-palette.json'),
];
const watcher = chokidar.watch(filesToWatch, {
persistent: true,
ignoreInitial: true,
});
watcher.on('change', async changedFile => {
if (isRegenerating) {
queuedRegeneration = true;
return;
}
isRegenerating = true;
console.log(`\n[color-registry-watcher] ${path.basename(changedFile)} changed, regenerating themes.css...`);
await regenerate(server);
while (queuedRegeneration) {
queuedRegeneration = false;
console.log('[color-registry-watcher] Processing queued change...');
await regenerate(server);
}
isRegenerating = false;
});
server.httpServer?.on('close', () => {
watcher.close();
});
},
};
}
// https://vitejs.dev/config/
export default defineConfig({
mode: process.env.MODE,
root: PACKAGE_ROOT,
resolve: {
alias: {
'/@/': join(PACKAGE_ROOT, 'src') + '/',
},
},
plugins: [
tailwindcss(),
svelte({ configFile: '../svelte.config.js', hot: true }),
svelteTesting(),
colorRegistryWatcher(),
],
test: {
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
globals: true,
environment: 'jsdom',
alias: [{ find: '@testing-library/svelte', replacement: '@testing-library/svelte/svelte5' }],
deps: {
inline: ['moment'],
},
},
base: '',
server: {
fs: {
strict: true,
},
watch: {
// Watch the UI package dist folder for changes
ignored: ['!**/node_modules/@podman-desktop/ui-svelte/**'],
},
},
build: {
sourcemap: true,
outDir: 'dist',
assetsDir: '.',
lib: {
entry: 'src/lib/index.ts',
formats: ['es'],
},
emptyOutDir: true,
reportCompressedSize: false,
},
});