Some checks failed
DSS Project Analysis / dss-context-update (push) Has been cancelled
- Button.css uses only CSS custom properties, no fallbacks - Token validator now blocks hardcoded values (strict_mode: true) - Hook scripts converted from ESM (.js) to CommonJS (.cjs) - Storybook unified config with HMR disabled for nginx proxy - Added dss-ui package with Figma-synced components and stories 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
239 lines
8.0 KiB
JavaScript
239 lines
8.0 KiB
JavaScript
/**
|
|
* DSS Unified Storybook Preview
|
|
*
|
|
* Single Storybook instance that loads:
|
|
* - DSS Core components (atoms, molecules, organisms)
|
|
* - Project-specific stories (templates, pages)
|
|
*
|
|
* Toolbar controls:
|
|
* - Skin: shadcn, material, heroui
|
|
* - Mode: light/dark
|
|
*/
|
|
|
|
import { h } from 'preact';
|
|
|
|
// Import all component CSS from DSS Core
|
|
const coreStyles = import.meta.glob('../packages/dss-ui/src/atoms/*.css', { eager: true });
|
|
|
|
// Import design tokens
|
|
import '../packages/dss-ui/src/primitives/tokens.css';
|
|
|
|
// Skin CSS variables - generated from skin dictionaries
|
|
const skinStyles = {
|
|
shadcn: {
|
|
'--color-background': 'hsl(0 0% 100%)',
|
|
'--color-foreground': 'hsl(240 10% 3.9%)',
|
|
'--color-card': 'hsl(0 0% 100%)',
|
|
'--color-card-foreground': 'hsl(240 10% 3.9%)',
|
|
'--color-popover': 'hsl(0 0% 100%)',
|
|
'--color-popover-foreground': 'hsl(240 10% 3.9%)',
|
|
'--color-primary': 'hsl(240 5.9% 10%)',
|
|
'--color-primary-foreground': 'hsl(0 0% 98%)',
|
|
'--color-secondary': 'hsl(240 4.8% 95.9%)',
|
|
'--color-secondary-foreground': 'hsl(240 5.9% 10%)',
|
|
'--color-muted': 'hsl(240 4.8% 95.9%)',
|
|
'--color-muted-foreground': 'hsl(240 3.8% 46.1%)',
|
|
'--color-accent': 'hsl(240 4.8% 95.9%)',
|
|
'--color-accent-foreground': 'hsl(240 5.9% 10%)',
|
|
'--color-destructive': 'hsl(0 84.2% 60.2%)',
|
|
'--color-destructive-foreground': 'hsl(0 0% 98%)',
|
|
'--color-border': 'hsl(240 5.9% 90%)',
|
|
'--color-input': 'hsl(240 5.9% 90%)',
|
|
'--color-ring': 'hsl(240 5.9% 10%)',
|
|
'--radius': '0.5rem',
|
|
},
|
|
material: {
|
|
'--color-background': 'hsl(0 0% 99%)',
|
|
'--color-foreground': 'hsl(0 0% 10%)',
|
|
'--color-card': 'hsl(0 0% 100%)',
|
|
'--color-card-foreground': 'hsl(0 0% 10%)',
|
|
'--color-popover': 'hsl(0 0% 100%)',
|
|
'--color-popover-foreground': 'hsl(0 0% 10%)',
|
|
'--color-primary': 'hsl(262 80% 50%)',
|
|
'--color-primary-foreground': 'hsl(0 0% 100%)',
|
|
'--color-secondary': 'hsl(262 20% 90%)',
|
|
'--color-secondary-foreground': 'hsl(262 80% 30%)',
|
|
'--color-muted': 'hsl(0 0% 96%)',
|
|
'--color-muted-foreground': 'hsl(0 0% 45%)',
|
|
'--color-accent': 'hsl(262 20% 95%)',
|
|
'--color-accent-foreground': 'hsl(262 80% 40%)',
|
|
'--color-destructive': 'hsl(0 75% 42%)',
|
|
'--color-destructive-foreground': 'hsl(0 0% 100%)',
|
|
'--color-border': 'hsl(0 0% 88%)',
|
|
'--color-input': 'hsl(0 0% 88%)',
|
|
'--color-ring': 'hsl(262 80% 50%)',
|
|
'--radius': '1rem',
|
|
},
|
|
heroui: {
|
|
'--color-background': 'hsl(0 0% 100%)',
|
|
'--color-foreground': 'hsl(240 6% 10%)',
|
|
'--color-card': 'hsl(0 0% 100%)',
|
|
'--color-card-foreground': 'hsl(240 6% 10%)',
|
|
'--color-popover': 'hsl(0 0% 100%)',
|
|
'--color-popover-foreground': 'hsl(240 6% 10%)',
|
|
'--color-primary': 'hsl(212 100% 48%)',
|
|
'--color-primary-foreground': 'hsl(0 0% 100%)',
|
|
'--color-secondary': 'hsl(270 60% 52%)',
|
|
'--color-secondary-foreground': 'hsl(0 0% 100%)',
|
|
'--color-muted': 'hsl(240 5% 96%)',
|
|
'--color-muted-foreground': 'hsl(240 4% 46%)',
|
|
'--color-accent': 'hsl(212 100% 95%)',
|
|
'--color-accent-foreground': 'hsl(212 100% 40%)',
|
|
'--color-destructive': 'hsl(0 72% 51%)',
|
|
'--color-destructive-foreground': 'hsl(0 0% 100%)',
|
|
'--color-border': 'hsl(240 6% 90%)',
|
|
'--color-input': 'hsl(240 6% 90%)',
|
|
'--color-ring': 'hsl(212 100% 48%)',
|
|
'--radius': '0.75rem',
|
|
},
|
|
};
|
|
|
|
// Dark mode overrides
|
|
const darkModeStyles = {
|
|
shadcn: {
|
|
'--color-background': 'hsl(240 10% 3.9%)',
|
|
'--color-foreground': 'hsl(0 0% 98%)',
|
|
'--color-card': 'hsl(240 10% 3.9%)',
|
|
'--color-card-foreground': 'hsl(0 0% 98%)',
|
|
'--color-popover': 'hsl(240 10% 3.9%)',
|
|
'--color-popover-foreground': 'hsl(0 0% 98%)',
|
|
'--color-primary': 'hsl(0 0% 98%)',
|
|
'--color-primary-foreground': 'hsl(240 5.9% 10%)',
|
|
'--color-secondary': 'hsl(240 3.7% 15.9%)',
|
|
'--color-secondary-foreground': 'hsl(0 0% 98%)',
|
|
'--color-muted': 'hsl(240 3.7% 15.9%)',
|
|
'--color-muted-foreground': 'hsl(240 5% 64.9%)',
|
|
'--color-accent': 'hsl(240 3.7% 15.9%)',
|
|
'--color-accent-foreground': 'hsl(0 0% 98%)',
|
|
'--color-destructive': 'hsl(0 62.8% 30.6%)',
|
|
'--color-destructive-foreground': 'hsl(0 0% 98%)',
|
|
'--color-border': 'hsl(240 3.7% 15.9%)',
|
|
'--color-input': 'hsl(240 3.7% 15.9%)',
|
|
'--color-ring': 'hsl(240 4.9% 83.9%)',
|
|
},
|
|
material: {
|
|
'--color-background': 'hsl(280 10% 8%)',
|
|
'--color-foreground': 'hsl(280 5% 90%)',
|
|
'--color-card': 'hsl(280 10% 12%)',
|
|
'--color-card-foreground': 'hsl(280 5% 90%)',
|
|
'--color-popover': 'hsl(280 10% 12%)',
|
|
'--color-popover-foreground': 'hsl(280 5% 90%)',
|
|
'--color-primary': 'hsl(262 80% 70%)',
|
|
'--color-primary-foreground': 'hsl(280 10% 8%)',
|
|
'--color-secondary': 'hsl(262 20% 25%)',
|
|
'--color-secondary-foreground': 'hsl(262 50% 85%)',
|
|
'--color-muted': 'hsl(280 10% 15%)',
|
|
'--color-muted-foreground': 'hsl(280 5% 60%)',
|
|
'--color-accent': 'hsl(262 20% 20%)',
|
|
'--color-accent-foreground': 'hsl(262 80% 80%)',
|
|
'--color-destructive': 'hsl(0 60% 50%)',
|
|
'--color-destructive-foreground': 'hsl(0 0% 100%)',
|
|
'--color-border': 'hsl(280 10% 20%)',
|
|
'--color-input': 'hsl(280 10% 20%)',
|
|
'--color-ring': 'hsl(262 80% 70%)',
|
|
},
|
|
heroui: {
|
|
'--color-background': 'hsl(240 10% 4%)',
|
|
'--color-foreground': 'hsl(0 0% 95%)',
|
|
'--color-card': 'hsl(240 10% 8%)',
|
|
'--color-card-foreground': 'hsl(0 0% 95%)',
|
|
'--color-popover': 'hsl(240 10% 8%)',
|
|
'--color-popover-foreground': 'hsl(0 0% 95%)',
|
|
'--color-primary': 'hsl(212 100% 55%)',
|
|
'--color-primary-foreground': 'hsl(0 0% 100%)',
|
|
'--color-secondary': 'hsl(270 60% 60%)',
|
|
'--color-secondary-foreground': 'hsl(0 0% 100%)',
|
|
'--color-muted': 'hsl(240 5% 15%)',
|
|
'--color-muted-foreground': 'hsl(240 4% 60%)',
|
|
'--color-accent': 'hsl(212 50% 15%)',
|
|
'--color-accent-foreground': 'hsl(212 100% 70%)',
|
|
'--color-destructive': 'hsl(0 72% 55%)',
|
|
'--color-destructive-foreground': 'hsl(0 0% 100%)',
|
|
'--color-border': 'hsl(240 6% 20%)',
|
|
'--color-input': 'hsl(240 6% 20%)',
|
|
'--color-ring': 'hsl(212 100% 55%)',
|
|
},
|
|
};
|
|
|
|
// Apply theme to document root
|
|
const applyTheme = (skin, mode) => {
|
|
const root = document.documentElement;
|
|
const styles = mode === 'dark'
|
|
? { ...skinStyles[skin], ...darkModeStyles[skin] }
|
|
: skinStyles[skin];
|
|
|
|
Object.entries(styles).forEach(([prop, value]) => {
|
|
root.style.setProperty(prop, value);
|
|
});
|
|
|
|
// Set background color on body for Storybook canvas
|
|
document.body.style.backgroundColor = styles['--color-background'];
|
|
document.body.style.color = styles['--color-foreground'];
|
|
};
|
|
|
|
/** @type { import('@storybook/preact').Preview } */
|
|
const preview = {
|
|
globalTypes: {
|
|
skin: {
|
|
description: 'Design system skin',
|
|
defaultValue: 'shadcn',
|
|
toolbar: {
|
|
title: 'Skin',
|
|
icon: 'paintbrush',
|
|
items: [
|
|
{ value: 'shadcn', title: 'shadcn/ui (Default)' },
|
|
{ value: 'material', title: 'Material Design' },
|
|
{ value: 'heroui', title: 'HeroUI' },
|
|
],
|
|
dynamicTitle: true,
|
|
},
|
|
},
|
|
mode: {
|
|
description: 'Color mode',
|
|
defaultValue: 'light',
|
|
toolbar: {
|
|
title: 'Mode',
|
|
icon: 'circlehollow',
|
|
items: [
|
|
{ value: 'light', title: 'Light', icon: 'sun' },
|
|
{ value: 'dark', title: 'Dark', icon: 'moon' },
|
|
],
|
|
dynamicTitle: true,
|
|
},
|
|
},
|
|
},
|
|
parameters: {
|
|
controls: {
|
|
matchers: {
|
|
color: /(background|color)$/i,
|
|
date: /Date$/i,
|
|
},
|
|
},
|
|
backgrounds: {
|
|
disable: true, // Use our custom theme system instead
|
|
},
|
|
options: {
|
|
storySort: {
|
|
order: [
|
|
'0. Overview',
|
|
'1. Primitives',
|
|
'2. Atoms',
|
|
'3. Molecules',
|
|
'4. Organisms',
|
|
'5. Templates', // Project-specific
|
|
'6. Pages', // Project-specific
|
|
],
|
|
},
|
|
},
|
|
},
|
|
decorators: [
|
|
(Story, context) => {
|
|
const { skin, mode } = context.globals;
|
|
applyTheme(skin || 'shadcn', mode || 'light');
|
|
return h(Story, null);
|
|
},
|
|
],
|
|
};
|
|
|
|
export default preview;
|