diff --git a/apps/docs/app/app.config.ts b/apps/docs/app/app.config.ts index 70ef46a3e..b574001d5 100644 --- a/apps/docs/app/app.config.ts +++ b/apps/docs/app/app.config.ts @@ -50,6 +50,11 @@ export default defineAppConfig({ branch: "main", rootDir: "apps/docs", }, + storybook: { + // Base URL of the deployed component-library Storybook. Component pages link + // to their autodocs page here (see DocsPageHeaderLinks.vue). + url: "https://storybook.meteor.shopware.com", + }, ui: { colors: { primary: "brand", diff --git a/apps/docs/app/assets/icons/storybook.svg b/apps/docs/app/assets/icons/storybook.svg new file mode 100644 index 000000000..d2b25ff38 --- /dev/null +++ b/apps/docs/app/assets/icons/storybook.svg @@ -0,0 +1,3 @@ + + + diff --git a/apps/docs/app/components/DocsPageHeaderLinks.vue b/apps/docs/app/components/DocsPageHeaderLinks.vue index 84b9c6fdd..a22d96591 100644 --- a/apps/docs/app/components/DocsPageHeaderLinks.vue +++ b/apps/docs/app/components/DocsPageHeaderLinks.vue @@ -22,16 +22,26 @@ const mcpServerUrl = computed( () => `${window?.location?.origin}${joinURL(appBaseURL, mcpRoute)}`, ); -// Link a component page to its source folder on GitHub. The slug -> folder map -// is provided at build time by modules/meteor-components.ts. -const componentSourceUrl = computed(() => { +// The slug -> repo-relative source folder map, provided at build time by +// modules/meteor-components.ts. Its keys double as the set of known components. +const componentSourcePaths = computed( + () => + (runtimeConfig.public.componentSourcePaths ?? {}) as Record, +); + +// The current component slug, or undefined outside a component page. Both the +// GitHub and Storybook links are gated on this so they only show for real +// components and always appear together. +const componentSlug = computed(() => { if (!route.path.startsWith("/components/")) return undefined; - const slug = route.path.split("/").filter(Boolean).pop() ?? ""; - const sources = (runtimeConfig.public.componentSourcePaths ?? {}) as Record< - string, - string - >; - const path = sources[slug]; + const slug = route.path.split("/").filter(Boolean).pop(); + return slug && componentSourcePaths.value[slug] ? slug : undefined; +}); + +// Link a component page to its source folder on GitHub. +const componentSourceUrl = computed(() => { + if (!componentSlug.value) return undefined; + const path = componentSourcePaths.value[componentSlug.value]; const github = appConfig.github as | { url?: string; branch?: string } | undefined; @@ -39,6 +49,16 @@ const componentSourceUrl = computed(() => { return `${github.url}/tree/${github.branch || "main"}/${path}`; }); +// Link a component page to its Storybook entry. The docs slug matches the +// Storybook id prefix (e.g. "data-table" -> components-data-table); Storybook +// resolves that to the component's autodocs (or first story) automatically. +const componentStorybookUrl = computed(() => { + if (!componentSlug.value) return undefined; + const storybook = appConfig.storybook as { url?: string } | undefined; + if (!storybook?.url) return undefined; + return `${storybook.url}/?path=/docs/components-${componentSlug.value}`; +}); + const items = computed(() => [ [ { @@ -78,12 +98,24 @@ async function copyPage() {