From 49c2c0d70de5610e66f07659e5b5bf0a136c5d36 Mon Sep 17 00:00:00 2001 From: yannbf Date: Tue, 24 Feb 2026 15:04:56 +0100 Subject: [PATCH 1/3] feat: add storybook playground link Co-Authored-By: Scott Wu --- app/components/Package/Playgrounds.vue | 2 ++ app/pages/package/[[org]]/[name].vue | 25 +++++++++++++++++++++---- uno.config.ts | 1 + 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/app/components/Package/Playgrounds.vue b/app/components/Package/Playgrounds.vue index e498d7433..5d1db8070 100644 --- a/app/components/Package/Playgrounds.vue +++ b/app/components/Package/Playgrounds.vue @@ -20,6 +20,7 @@ const providerIcons: Record = { 'solid-playground': 'i-simple-icons:solid', 'svelte-playground': 'i-simple-icons:svelte', 'tailwind-playground': 'i-simple-icons:tailwindcss', + 'storybook': 'i-simple-icons:storybook', } // Map provider id to color class @@ -37,6 +38,7 @@ const providerColors: Record = { 'solid-playground': 'text-provider-solid', 'svelte-playground': 'text-provider-svelte', 'tailwind-playground': 'text-provider-tailwind', + 'storybook': 'text-provider-storybook', } function getIcon(provider: string): string { diff --git a/app/pages/package/[[org]]/[name].vue b/app/pages/package/[[org]]/[name].vue index 3b92a9975..bc6330d25 100644 --- a/app/pages/package/[[org]]/[name].vue +++ b/app/pages/package/[[org]]/[name].vue @@ -109,6 +109,26 @@ const { data: readmeData } = useLazyFetch( { default: () => ({ html: '', mdExists: false, playgroundLinks: [], toc: [] }) }, ) +const { data: packageJson } = useLazyFetch<{ storybook?: { title: string; url: string } }>(() => { + const version = requestedVersion.value ?? 'latest' + return `https://cdn.jsdelivr.net/npm/${packageName.value}@${version}/package.json` +}) + +const playgroundLinks = computed(() => [ + ...readmeData.value.playgroundLinks, + // Libraries with a storybook field in package.json contain a link to their deployed playground + ...(packageJson.value?.storybook + ? [ + { + url: packageJson.value.storybook.url, + provider: 'storybook', + providerName: 'Storybook', + label: 'Storybook', + }, + ] + : []), +]) + const { data: readmeMarkdownData, status: readmeMarkdownStatus, @@ -1387,10 +1407,7 @@ const showSkeleton = shallowRef(false) /> - + diff --git a/uno.config.ts b/uno.config.ts index d0821dc7f..506c8977d 100644 --- a/uno.config.ts +++ b/uno.config.ts @@ -104,6 +104,7 @@ export default defineConfig({ solid: '#2C4F7C', svelte: '#FF3E00', tailwind: '#06B6D4', + storybook: '#FF4785', }, }, animation: { From b38a4b5088cbee09894ef7ba14a7f4006456369a Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Tue, 24 Feb 2026 16:00:52 +0000 Subject: [PATCH 2/3] fix: include storybook data in slim packument --- app/composables/npm/usePackage.ts | 9 +++++++++ app/pages/package/[[org]]/[name].vue | 9 ++------- shared/types/npm-registry.ts | 1 + 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/app/composables/npm/usePackage.ts b/app/composables/npm/usePackage.ts index 1bfef0198..7b316a91f 100644 --- a/app/composables/npm/usePackage.ts +++ b/app/composables/npm/usePackage.ts @@ -120,6 +120,14 @@ export function transformPackument( license = license.type } + // Extract storybook field from the requested version (custom package.json field) + const requestedPkgVersion = requestedVersion ? pkg.versions[requestedVersion] : null + const rawStorybook = requestedPkgVersion?.storybook + const storybook = + rawStorybook && typeof rawStorybook === 'object' && 'url' in rawStorybook + ? (rawStorybook as { title?: string; url: string }) + : undefined + return { '_id': pkg._id, '_rev': pkg._rev, @@ -134,6 +142,7 @@ export function transformPackument( 'keywords': pkg.keywords, 'repository': pkg.repository, 'bugs': pkg.bugs, + ...(storybook && { storybook }), 'requestedVersion': versionData, 'versions': filteredVersions, 'securityVersions': securityVersions, diff --git a/app/pages/package/[[org]]/[name].vue b/app/pages/package/[[org]]/[name].vue index bc6330d25..26bf4b2f0 100644 --- a/app/pages/package/[[org]]/[name].vue +++ b/app/pages/package/[[org]]/[name].vue @@ -109,18 +109,13 @@ const { data: readmeData } = useLazyFetch( { default: () => ({ html: '', mdExists: false, playgroundLinks: [], toc: [] }) }, ) -const { data: packageJson } = useLazyFetch<{ storybook?: { title: string; url: string } }>(() => { - const version = requestedVersion.value ?? 'latest' - return `https://cdn.jsdelivr.net/npm/${packageName.value}@${version}/package.json` -}) - const playgroundLinks = computed(() => [ ...readmeData.value.playgroundLinks, // Libraries with a storybook field in package.json contain a link to their deployed playground - ...(packageJson.value?.storybook + ...(pkg.value?.storybook ? [ { - url: packageJson.value.storybook.url, + url: pkg.value.storybook.url, provider: 'storybook', providerName: 'Storybook', label: 'Storybook', diff --git a/shared/types/npm-registry.ts b/shared/types/npm-registry.ts index 00558913c..9db9fb4b4 100644 --- a/shared/types/npm-registry.ts +++ b/shared/types/npm-registry.ts @@ -83,6 +83,7 @@ export interface SlimPackument { 'keywords'?: string[] 'repository'?: { type?: string; url?: string; directory?: string } 'bugs'?: { url?: string; email?: string } + 'storybook'?: { title?: string; url: string } /** current version */ 'requestedVersion': SlimPackumentVersion | null /** Only includes dist-tag versions (with installScripts info added per version) */ From 39259f4cc8f471a62c12756f73e154e4fc96014f Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Tue, 24 Feb 2026 16:03:56 +0000 Subject: [PATCH 3/3] chore: check url existence only --- app/composables/npm/usePackage.ts | 2 +- app/pages/package/[[org]]/[name].vue | 2 +- shared/types/npm-registry.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/composables/npm/usePackage.ts b/app/composables/npm/usePackage.ts index 7b316a91f..96bab1592 100644 --- a/app/composables/npm/usePackage.ts +++ b/app/composables/npm/usePackage.ts @@ -125,7 +125,7 @@ export function transformPackument( const rawStorybook = requestedPkgVersion?.storybook const storybook = rawStorybook && typeof rawStorybook === 'object' && 'url' in rawStorybook - ? (rawStorybook as { title?: string; url: string }) + ? ({ url: rawStorybook.url } as { url: string }) : undefined return { diff --git a/app/pages/package/[[org]]/[name].vue b/app/pages/package/[[org]]/[name].vue index 5a16362fd..8744e2e52 100644 --- a/app/pages/package/[[org]]/[name].vue +++ b/app/pages/package/[[org]]/[name].vue @@ -112,7 +112,7 @@ const { data: readmeData } = useLazyFetch( const playgroundLinks = computed(() => [ ...readmeData.value.playgroundLinks, // Libraries with a storybook field in package.json contain a link to their deployed playground - ...(pkg.value?.storybook + ...(pkg.value?.storybook?.url ? [ { url: pkg.value.storybook.url, diff --git a/shared/types/npm-registry.ts b/shared/types/npm-registry.ts index 9db9fb4b4..f7d7cdd12 100644 --- a/shared/types/npm-registry.ts +++ b/shared/types/npm-registry.ts @@ -83,7 +83,7 @@ export interface SlimPackument { 'keywords'?: string[] 'repository'?: { type?: string; url?: string; directory?: string } 'bugs'?: { url?: string; email?: string } - 'storybook'?: { title?: string; url: string } + 'storybook'?: { url: string } /** current version */ 'requestedVersion': SlimPackumentVersion | null /** Only includes dist-tag versions (with installScripts info added per version) */