feat(design-system): Storybook + Button-Atom-Vereinheitlichung + SectionHeader
Storybook (SvelteKit-Framework, Tailwind v4, MSW, Translation-Decorator): Stories für Atoms/Molecules/Organisms + alle CMS-Blocks. Button-Atom: 5 .btn-*-Varianten (primary/secondary/tertiary/outline/warning), class-Merge-Prop, href→<a>, Loading-Spinner neben Label, rounded-md/font-medium. Alle rohen .btn-*- und Hand-Style-Buttons app-weit aufs Atom migriert. SectionHeader-Molecule (kicker/number/title/subtitle/action) + Integration in 7 CMS-Blocks (post_overview, organisations, organisations_map, searchable_text, image_gallery, youtube_video_gallery, files) via neuem section_header-Schema. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from 'svelte';
|
||||
import TranslationProvider from '$lib/components/TranslationProvider.svelte';
|
||||
import strings from '$lib/components/blocks/_fixtures/translations.json';
|
||||
|
||||
// Storybook reicht die Story als `children`-Snippet rein. Wir setzen den
|
||||
// Translation-Context (echte deutsche Strings aus dem CMS-Bundle), damit
|
||||
// Blocks lesbare Texte statt roher Keys zeigen.
|
||||
let { children }: { children: Snippet } = $props();
|
||||
</script>
|
||||
|
||||
<TranslationProvider translations={strings}>
|
||||
{@render children()}
|
||||
</TranslationProvider>
|
||||
@@ -0,0 +1,40 @@
|
||||
import type { StorybookConfig } from '@storybook/sveltekit';
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
|
||||
const config: StorybookConfig = {
|
||||
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|ts|svelte)'],
|
||||
addons: [
|
||||
'@storybook/addon-svelte-csf',
|
||||
'@storybook/addon-a11y',
|
||||
'@storybook/addon-docs',
|
||||
],
|
||||
framework: '@storybook/sveltekit',
|
||||
// MSW-Service-Worker liegt in static/ (via `npx msw init static/`). Storybook
|
||||
// muss static/ ausliefern, damit /mockServiceWorker.js erreichbar ist.
|
||||
staticDirs: ['../static'],
|
||||
// Tailwind v4 läuft als Vite-Plugin. Das sveltekit-Framework bringt nur die
|
||||
// Svelte/SvelteKit-Integration mit ($app/$env/$lib-Mocks), nicht Tailwind —
|
||||
// darum hier explizit dazuhängen, sonst greifen keine Utility-Klassen/Tokens.
|
||||
viteFinal: async (viteConfig) => {
|
||||
viteConfig.plugins = viteConfig.plugins ?? [];
|
||||
viteConfig.plugins.push(tailwindcss());
|
||||
|
||||
// Same-origin-Routen, die im echten Frontend SvelteKit-Server-Endpoints
|
||||
// sind (in Storybook nicht existieren), auf die Live-Site proxien. Damit
|
||||
// rendern RustyImage-Bilder (/cms-images, /cms-files) und die Live-Daten-
|
||||
// Blocks (/api/strommix, /api/stellungnahme) mit echten Daten — ohne
|
||||
// Fixtures. Deterministische Offline-Mocks stattdessen via MSW (siehe
|
||||
// .storybook/README oder Kommentar unten).
|
||||
const PROXY_TARGET = 'https://windwiderstand.de';
|
||||
viteConfig.server = viteConfig.server ?? {};
|
||||
viteConfig.server.proxy = {
|
||||
...(viteConfig.server.proxy ?? {}),
|
||||
'/cms-images': { target: PROXY_TARGET, changeOrigin: true },
|
||||
'/cms-files': { target: PROXY_TARGET, changeOrigin: true },
|
||||
'/api/strommix': { target: PROXY_TARGET, changeOrigin: true },
|
||||
'/api/stellungnahme': { target: PROXY_TARGET, changeOrigin: true },
|
||||
};
|
||||
return viteConfig;
|
||||
},
|
||||
};
|
||||
export default config;
|
||||
@@ -0,0 +1,13 @@
|
||||
<!--
|
||||
SvelteKit liest $env/dynamic/public im Browser aus globalThis.__sveltekit_dev.env.
|
||||
Dieses Global setzt sonst nur der echte SvelteKit-Dev-Server. In Storybook hier
|
||||
vorab setzen, sonst crasht jede Komponente mit `env.PUBLIC_*` (Windkarte,
|
||||
Stellingnahme, …) mit "__sveltekit_dev is undefined". Läuft vor dem Story-Bundle.
|
||||
-->
|
||||
<script>
|
||||
window.__sveltekit_dev = window.__sveltekit_dev || { env: {} };
|
||||
window.__sveltekit_dev.env = Object.assign(
|
||||
{ PUBLIC_CMS_URL: 'https://cms.pm86.de' },
|
||||
window.__sveltekit_dev.env,
|
||||
);
|
||||
</script>
|
||||
@@ -0,0 +1,54 @@
|
||||
import type { Preview } from '@storybook/sveltekit';
|
||||
import { initialize, mswLoader } from 'msw-storybook-addon';
|
||||
import WithTranslations from './decorators/WithTranslations.svelte';
|
||||
// Design-System-Styles: Fonts, Tailwind, Farbtokens (wald/erde/…). Zieht die
|
||||
// echte app.css des Frontends → Stories sehen aus wie live.
|
||||
import '../src/app.css';
|
||||
|
||||
// MSW starten. `onUnhandledRequest: 'bypass'` → Requests ohne Handler laufen
|
||||
// normal durch (z.B. der Vite-Proxy für /cms-images). Nur explizit gemockte
|
||||
// Endpoints werden abgefangen → Blocks mit fetch entwickeln sich deterministisch
|
||||
// offline, per Story via `parameters.msw.handlers`.
|
||||
initialize({ onUnhandledRequest: 'bypass' });
|
||||
|
||||
// Default-Mock für den SvelteKit-page-Store/-State ($app/stores + $app/state).
|
||||
// Ohne das crasht jede Komponente, die $page.url liest (Header, PostActions, …).
|
||||
// Einzelne Stories können via parameters.sveltekit_experimental überschreiben.
|
||||
const mockPage = {
|
||||
url: new URL('http://localhost:6006/'),
|
||||
params: {},
|
||||
route: { id: null },
|
||||
status: 200,
|
||||
error: null,
|
||||
data: {},
|
||||
form: null,
|
||||
state: {},
|
||||
};
|
||||
|
||||
const preview: Preview = {
|
||||
loaders: [mswLoader],
|
||||
// Alle Stories in den Translation-Context wrappen → echte Texte statt Keys.
|
||||
decorators: [() => WithTranslations],
|
||||
parameters: {
|
||||
sveltekit_experimental: {
|
||||
stores: { page: mockPage },
|
||||
state: { page: mockPage },
|
||||
},
|
||||
controls: {
|
||||
matchers: {
|
||||
color: /(background|color)$/i,
|
||||
date: /Date$/i,
|
||||
},
|
||||
},
|
||||
// Frontend rendert auf hellem Grund; Storybook-Canvas dazu passend.
|
||||
backgrounds: {
|
||||
default: 'weiss',
|
||||
values: [
|
||||
{ name: 'weiss', value: '#ffffff' },
|
||||
{ name: 'stein', value: '#f5f5f4' },
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default preview;
|
||||
Reference in New Issue
Block a user