Skip to content
Closed
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion code/addons/vitest/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
"types": ["vitest"],
"strict": true
},
"include": ["src/**/*", "./typings.d.ts"],
"include": ["src/**/*", "./typings.d.ts"]
}
2 changes: 1 addition & 1 deletion code/core/src/core-server/build-static.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ export async function buildStaticStandalone(options: BuildStaticStandaloneOption
);

if (features?.experimentalComponentsManifest) {
const componentManifestGenerator: ComponentManifestGenerator = await presets.apply(
const componentManifestGenerator = await presets.apply(
'experimental_componentManifestGenerator'
);
const indexGenerator = await initializedStoryIndexGenerator;
Expand Down
4 changes: 2 additions & 2 deletions code/core/src/core-server/dev-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export async function storybookDevServer(options: Options) {
if (features?.experimentalComponentsManifest) {
app.use('/manifests/components.json', async (req, res) => {
try {
const componentManifestGenerator: ComponentManifestGenerator = await options.presets.apply(
const componentManifestGenerator = await options.presets.apply(
'experimental_componentManifestGenerator'
);
const indexGenerator = await initializedStoryIndexGenerator;
Expand All @@ -169,7 +169,7 @@ export async function storybookDevServer(options: Options) {

app.get('/manifests/components.html', async (req, res) => {
try {
const componentManifestGenerator: ComponentManifestGenerator = await options.presets.apply(
const componentManifestGenerator = await options.presets.apply(
'experimental_componentManifestGenerator'
);
const indexGenerator = await initializedStoryIndexGenerator;
Expand Down
52 changes: 48 additions & 4 deletions code/core/src/core-server/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export function renderManifestComponentsPage(manifest: ComponentsManifest) {
entries.map(([, it]) => it).filter((it) => it.error),
(manifest) => manifest.error?.name ?? 'Error'
)
);
).sort(([, a], [, b]) => b.length - a.length);

const errorGroupsHTML = errorGroups
.map(([error, grouped]) => {
Expand Down Expand Up @@ -517,15 +517,23 @@ export function renderManifestComponentsPage(manifest: ComponentsManifest) {
.card > .tg-err:checked ~ .panels .panel-err {
display: grid;
}

.card > .tg-warn:checked ~ .panels .panel-warn {
display: grid;
}

.card > .tg-stories:checked ~ .panels .panel-stories {
display: grid;
}
Comment on lines +520 to 527
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove or complete empty CSS rule blocks.

These CSS rule blocks appear to be incomplete or placeholder code. They should either be removed or completed with the intended styles.

-      
-      .card > .tg-warn:checked ~ .panels .panel-warn {
-          display: grid;
-      }
-      
-      .card > .tg-stories:checked ~ .panels .panel-stories {
-          display: grid;
-      }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.card > .tg-warn:checked ~ .panels .panel-warn {
display: grid;
}
.card > .tg-stories:checked ~ .panels .panel-stories {
display: grid;
}
🤖 Prompt for AI Agents
In code/core/src/core-server/manifest.ts around lines 520 to 527, there are two
CSS rule blocks that look like incomplete placeholders (.card > .tg-warn:checked
~ .panels .panel-warn and .card > .tg-stories:checked ~ .panels .panel-stories);
either remove these rules entirely if they are not needed, or complete them with
the intended panel styles (for example set grid-template-columns/rows, gap,
align-items, padding, and any show/hide behavior) so they’re not empty
placeholders — choose one of those two options and update the file accordingly.


/* Add vertical spacing around panels only when any panel is visible */
.card > .tg-err:checked ~ .panels,
.card > .tg-warn:checked ~ .panels,
.card > .tg-stories:checked ~ .panels,
.card > .tg-props:checked ~ .panels {
margin: 10px 0;
}

/* Optional: a subtle 1px ring on the active badge, using :has() if available */
@supports selector(.card:has(.tg-err:checked)) {
.card:has(.tg-err:checked) label[for$='-err'],
Expand All @@ -536,6 +544,25 @@ export function renderManifestComponentsPage(manifest: ComponentsManifest) {
border-color: currentColor;
}
}

/* Wrap long lines in code blocks at ~120 characters */
pre, code {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
}
pre {
white-space: pre-wrap;
overflow-wrap: anywhere;
word-break: break-word;
overflow-x: auto; /* fallback for extremely long tokens */
margin: 8px 0 0;
}
pre > code {
display: block;
white-space: inherit;
overflow-wrap: inherit;
word-break: inherit;
inline-size: min(100%, 120ch);
}
</style>
</head>
<body>
Expand Down Expand Up @@ -747,19 +774,36 @@ function renderComponentCard(key: string, c: ComponentManifest, id: string) {
<span class="ex-name">${esc(ex.name)}</span>
<span class="badge err">story error</span>
</div>
${ex?.summary ? `<div>${esc(ex.summary)}</div>` : ''}
${ex?.description ? `<div class=\"hint\">${esc(ex.description)}</div>` : ''}
${ex?.snippet ? `<pre><code>${esc(ex.snippet)}</code></pre>` : ''}
${ex?.error?.message ? `<pre><code>${esc(ex.error.message)}</code></pre>` : ''}
</div>`
)
.join('')}


${
c.import
? `<div class="note ok">
<div class="row">
<span class="ex-name">Imports</span>
</div>
<pre><code>${c.import}</code></pre>
</div>`
: ''
}
Comment on lines +784 to +795
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Escape import content to prevent XSS.

The import string c.import is rendered without escaping, which could lead to XSS vulnerabilities if the import content contains malicious HTML/script tags.

Apply the esc() function:

           ${
             c.import
               ? `<div class="note ok">
                 <div class="row">
                   <span class="ex-name">Imports</span>
                 </div>
-                <pre><code>${c.import}</code></pre>
+                <pre><code>${esc(c.import)}</code></pre>
               </div>`
               : ''
           }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In code/core/src/core-server/manifest.ts around lines 782 to 793, the template
renders c.import unescaped which can lead to XSS; replace the raw interpolation
with an escaped value (e.g., use esc(c.import) or esc(String(c.import))) when
inserting into the <pre><code> block, and ensure the esc function is
imported/available in this module; keep the conditional logic the same but wrap
the displayed content in esc(...) to prevent HTML/script injection.


${okStories
.map(
(ex, k) => `
(ex) => `
<div class="note ok">
<div class="row">
<span class="ex-name">${esc(ex.name)}</span>
<span class="badge ok">story ok</span>
</div>
${ex?.summary ? `<div>${esc(ex.summary)}</div>` : ''}
${ex?.description ? `<div class=\"hint\">${esc(ex.description)}</div>` : ''}
${ex?.snippet ? `<pre><code>${esc(ex.snippet)}</code></pre>` : ''}
</div>`
)
Expand Down
8 changes: 7 additions & 1 deletion code/core/src/types/modules/core-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,13 @@ export interface ComponentManifest {
description?: string;
import?: string;
summary?: string;
stories: { name: string; snippet?: string; error?: { name: string; message: string } }[];
stories: {
name: string;
snippet?: string;
description?: string;
summary?: string;
error?: { name: string; message: string };
}[];
jsDocTags: Record<string, string[]>;
error?: { name: string; message: string };
}
Expand Down
1 change: 1 addition & 0 deletions code/renderers/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"acorn-walk": "^7.2.0",
"babel-plugin-react-docgen": "^4.2.1",
"comment-parser": "^1.4.1",
"empathic": "^2.0.0",
"es-toolkit": "^1.36.0",
"escodegen": "^2.1.0",
"expect-type": "^0.15.0",
Expand Down
Loading
Loading