Skip to content

Conversation

@valentinpalkovic
Copy link
Contributor

@valentinpalkovic valentinpalkovic commented Nov 11, 2025

Closes #

What I did

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • stories
  • unit tests
  • integration tests
  • end-to-end tests

Manual testing

This section is mandatory for all contributions. If you believe no manual test is necessary, please state so explicitly. Thanks!

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli-storybook/src/sandbox-templates.ts

  • Make sure this PR contains one of the labels below:

    Available labels
    • bug: Internal changes that fixes incorrect behavior.
    • maintenance: User-facing maintenance tasks.
    • dependencies: Upgrading (sometimes downgrading) dependencies.
    • build: Internal-facing build tooling & test updates. Will not show up in release changelog.
    • cleanup: Minor cleanup style change. Will not show up in release changelog.
    • documentation: Documentation only changes. Will not show up in release changelog.
    • feature request: Introducing a new feature.
    • BREAKING CHANGE: Changes that break compatibility in some way with current major version.
    • other: Changes that don't fit in the above categories.

🦋 Canary release

This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the @storybookjs/core team here.

core team members can create a canary release here or locally with gh workflow run --repo storybookjs/storybook publish.yml --field pr=<PR_NUMBER>

Summary by CodeRabbit

  • Chores

    • Various internal cleanups: consolidated imports, removed unused parameters/variables, and simplified styling initializations.
  • Tests

    • Updated test fixtures to evaluate rendered expressions and simplified test callbacks to remove unused arguments.
  • Docs

    • Cleaned up story examples and event handlers for more consistent behavior.
  • Chores

    • Minor public type/signature refinements (no functional changes).

…ce no-unused-vars rule, and adjust consistent-type-imports style
@valentinpalkovic valentinpalkovic self-assigned this Nov 11, 2025
@valentinpalkovic valentinpalkovic added ci:daily Run the CI jobs that normally run in the daily job. maintenance User-facing maintenance tasks labels Nov 11, 2025
@valentinpalkovic valentinpalkovic changed the title Build: Apply stricter eslint rules for unused vars Maintenance: Apply stricter eslint rules for unused vars Nov 11, 2025
@nx-cloud
Copy link

nx-cloud bot commented Nov 11, 2025

🤖 Nx Cloud AI Fix Eligible

An automatically generated fix could have helped fix failing tasks for this run, but Self-healing CI is disabled for this workspace. Visit workspace settings to enable it and get automatic fixes in future runs.

To disable these notifications, a workspace admin can disable them in workspace settings.


View your CI Pipeline Execution ↗ for commit 1fe3404

Command Status Duration Result
nx run-many -t check -c production --parallel=7 ❌ Failed 9s View ↗
nx run-many -t build -c production --parallel=3 ✅ Succeeded 2s View ↗

☁️ Nx Cloud last updated this comment at 2025-11-11 12:28:17 UTC

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 11, 2025

📝 Walkthrough

Walkthrough

Repository-wide cleanup: removed unused imports/params, consolidated imports, simplified catch handlers, adjusted function/type parameter names (often underscore-prefixed), fixed test fixtures to evaluate JSON.stringify, and trimmed some story/play and plugin hook arities. No new features added.

Changes

Cohort / File(s) Summary
Unused-imports & lint directives
code/addons/docs/src/blocks/blocks/ArgTypes.stories.tsx, code/addons/docs/src/blocks/blocks/Controls.stories.tsx, code/addons/docs/src/blocks/blocks/Description.stories.tsx, code/addons/docs/src/blocks/blocks/Story.stories.tsx, code/addons/pseudo-states/src/stories/CSSAtRules.stories.tsx, code/addons/vitest/src/components/TestProviderRender.stories.tsx, code/core/template/stories/expect.stories.tsx, code/core/template/stories/test/ModuleAutoMocking.stories.ts, ...*
Removed unused React/type imports and added file-level ESLint disable comments where intentional; no runtime changes.
Parameter renames to mark unused
code/__mocks__/lodash-es/add.js, code/core/template/__mocks__/lodash-es/add.js, code/addons/a11y/src/manager.tsx, code/core/src/channels/index.test.ts, code/core/src/manager/components/layout/useDragging.ts, code/core/src/manager/components/preview/tools/zoom.tsx, code/addons/themes/src/decorators/class-name.decorator.tsx, ...*
Renamed parameters (e.g., a_a, err_err) or added underscore prefixes; behavior unchanged.
Import consolidation / reorders
code/addons/vitest/src/preset.ts, code/addons/vitest/src/types.ts, code/addons/vitest/src/vitest-plugin/index.ts, code/core/scripts/generate-source-files.ts, code/core/src/preview-api/modules/preview-web/PreviewWeb.tsx, code/core/src/manager/components/sidebar/Sidebar.tsx, code/core/src/manager/utils/status.tsx, ...*
Merged multiple imports from same modules into single statements or consolidated type imports; stylistic only.
Styled-component theme removal
code/addons/docs/src/blocks/components/ArgsTable/SectionRow.tsx, code/core/src/manager/components/sidebar/FileList.tsx, code/core/src/manager/components/sidebar/FileSearchListSkeleton.tsx, code/core/src/manager/components/preview/utils/components.ts, code/core/src/manager/components/sidebar/SearchResults.tsx, code/core/src/components/components/tooltip/ListItem.tsx
Converted styled callbacks that accepted theme into plain style object forms, dropping the theme parameter while keeping style rules.
Callback / hook arity changes
code/addons/docs/src/blocks/blocks/mdx.tsx, code/addons/docs/src/blocks/components/Preview.tsx, code/builders/builder-vite/src/plugins/code-generator-plugin.ts, code/builders/builder-vite/src/plugins/external-globals-plugin.ts, code/builders/builder-webpack5/src/index.ts, code/core/src/manager-api/modules/addons.ts, code/core/src/manager-api/modules/refs.ts, code/core/template/stories/decorators.stories.ts, code/frameworks/nextjs-vite/template/stories/Redirect.stories.tsx, ...*
Removed unused callback parameters or reduced function arity (many handlers/plugins/stories now accept fewer args); internal flow preserved.
Test mocks, snapshots & signatures
code/addons/a11y/src/components/A11yContext.test.tsx, code/addons/links/src/react/components/link.test.tsx, code/addons/vitest/src/node/boot-test-runner.test.ts, code/core/src/common/presets.test.ts, code/core/src/core-server/presets/favicon.test.ts, code/core/src/preview-api/modules/preview-web/PreviewWeb.test.ts, ...*
Simplified mock implementations (dropped unused params) and updated snapshots/expectations to match new outputs.
Test-fixture JSX fixes (JSON.stringify)
code/core/src/docs-tools/argTypes/convert/__testfixtures__/proptypes/*.js, code/core/src/docs-tools/argTypes/convert/__testfixtures__/typescript/*.tsx, code/core/src/docs-tools/argTypes/convert/convert.test.ts
Replaced literal "JSON.stringify(props)" with evaluated {JSON.stringify(props)} so fixtures render actual stringified props.
Catch-clause simplifications
code/core/src/common/utils/formatter.ts, code/core/src/core-server/utils/StoryIndexGenerator.ts, code/core/src/docs-tools/argTypes/jsdocParser.ts, code/core/src/shared/utils/module.ts, code/core/src/telemetry/anonymous-id.ts, code/core/src/telemetry/telemetry.ts
Converted catch (err)/catch (_) to bare catch blocks, removing unused error bindings.
Angular & Next.js API/logic adjustments
code/frameworks/angular/src/client/angular-beta/ComputesTemplateFromComponent.ts, code/frameworks/angular/src/client/docs/sourceDecorator.ts, code/frameworks/angular/template/stories/.../custom.pipe.ts, code/frameworks/nextjs/src/routing/app-router-provider.tsx, code/frameworks/nextjs-vite/src/routing/app-router-provider.tsx
Removed ArgTypes from Angular template generation, simplified computesTemplateFromComponent signature; Next.js app-router providers removed PAGE_SEGMENT_KEY and simplified route param extraction. Review for API impact advised.
Miscellaneous small refactors
code/core/src/actions/addArgsHelpers.ts, code/core/src/core-server/utils/watch-story-specifiers.ts, code/core/src/core-server/utils/watchConfig.ts, code/core/src/shared/status-store/index.test.ts, code/core/src/shared/test-provider-store/index.test.ts, code/core/src/manager/components/notifications/NotificationItem.tsx, ...*
Destructuring tweaks, removed unused locals, minor signature/type parameter renames, and test adaptations.

Notes: "..." and "*" indicate additional related files with equivalent changes summarized above.

Sequence Diagram(s)

(Skipped) — changes are widespread refactors and signature cleanups without a single new control-flow feature warranting a sequence diagram.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Files/areas needing extra attention:
    • Styled-component theme removals (verify runtime styles: FileList, SearchResults, IframeWrapper).
    • Angular template generator and source decorator changes (ensure computed templates remain correct without ArgTypes).
    • Next.js/NextJS-Vite app-router provider simplifications (confirm route param extraction correctness).
    • Plugin hook signature reductions (vite/webpack plugin hooks: ensure callers don't rely on removed params).
    • Test-fixture changes (JSON.stringify) — verify updated snapshots and test expectations.

Possibly related PRs

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🧹 Nitpick comments (7)
code/core/src/csf/story.test.ts (1)

1-1: Consider a more granular approach for unused variables in type-checking files.

The blanket eslint-disable suppresses all no-unused-vars warnings for the entire file. For a type-checking test file like this, where unused parameters and variables are intentional (e.g., (storyFn, context) decorators, example components used only for type inference), this may be acceptable. However, the coding guidelines recommend fixing ESLint errors rather than disabling them broadly.

Consider whether unused parameters could instead be:

  • Prefixed with underscore (e.g., (_context)) to explicitly mark them as intentionally unused
  • Removed if truly unnecessary
  • Suppressed granularly with eslint-disable-next-line comments on specific lines

Please verify:

  1. Is this blanket-disable approach consistent across other type-checking/mock test files in this PR?
  2. Is this the intended strategy for test files that inherently have unused type-example variables?
  3. Would underscore-prefixed parameters be a better fit given the PR's focus on stricter linting?
code/frameworks/angular/src/client/angular-beta/__testfixtures__/input.component.ts (1)

21-21: LGTM! Underscore prefix correctly indicates unused type parameter.

The rename from T to _T properly follows TypeScript/ESLint conventions for unused generic type parameters and aligns with the PR's objective to enforce stricter unused variable rules.

Since this is a test fixture and the type parameter is not used anywhere in the component, you may consider removing it entirely if it doesn't serve a specific testing purpose:

-export class InputComponent<_T> {
+export class InputComponent {

However, if the generic is intentionally present for API compatibility testing or future extensibility, the underscore prefix is the appropriate approach.

code/frameworks/angular/template/stories/basics/component-with-pipe/custom.pipe.ts (1)

9-11: Correctly removes unused parameter.

The removal of the unused args parameter is appropriate and consistent with the change in code/frameworks/angular/template/stories/core/moduleMetadata/angular-src/custom.pipe.ts.

Note: This pipe implementation is identical to the one in code/frameworks/angular/template/stories/core/moduleMetadata/angular-src/custom.pipe.ts. If these story examples don't require isolated implementations, consider consolidating them to reduce duplication. However, keeping separate implementations may be intentional for independent story demonstrations.

code/core/src/cli/helpers.test.ts (2)

113-113: LGTM – Unused parameter correctly removed.

The removal of the unused pkg parameter from this mock is correct and aligns with the PR's goal of enforcing stricter unused variable rules.

Note: This mock implementation is defined inline within the test case. Per coding guidelines, mock implementations should be placed in beforeEach blocks rather than inside individual test cases. The same pattern appears at lines 92–96. Consider extracting these to beforeEach for consistency. Based on coding guidelines.


28-67: Consider adding spy: true option to mocks.

The coding guidelines specify using vi.mock() with the spy: true option for all package and file mocks in Vitest tests. None of the mocks in this file currently use this option.

Example for the node:fs mock:

-vi.mock('node:fs', async (importOriginal) => {
+vi.mock('node:fs', { spy: true }, async (importOriginal) => {
   const actual = await importOriginal<typeof import('node:fs')>();
   return {
     ...actual,

Based on coding guidelines.

code/frameworks/angular/src/client/angular-beta/ComputesTemplateFromComponent.test.ts (1)

611-623: Consider updating the describe block name.

The describe block is named "with argTypes (from compodoc)" but the tests no longer pass argTypes to the function. While the tests still validate similar prop handling behavior, the name may be misleading.

Consider renaming to something like:

-  describe('with argTypes (from compodoc)', () => {
+  describe('with complex prop types', () => {

This is optional and can be deferred if preferred.

code/core/template/__mocks__/lodash-es/add.js (1)

1-3: Consider maintaining parameter signature for mock clarity.

While removing unused parameters is valid, mock functions typically benefit from maintaining the same signature as the real function for clarity and to avoid confusion. Consider using underscore-prefixed parameters to indicate they're intentionally unused.

-function add() {
+function add(_a, _b) {
   return 'mocked 3';
 }

@valentinpalkovic valentinpalkovic force-pushed the valentin/apply-stricter-unused-var-eslint-rules branch from 9458443 to 44dc6e2 Compare November 11, 2025 11:53
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
code/addons/docs/src/blocks/examples/ControlsParameters.tsx (1)

1-1: Suppressing unused-vars warnings contradicts the PR objective.

The PR aims to apply stricter ESLint rules for unused variables, but this change disables the rule instead. Since this is an example file demonstrating Controls functionality, the unused parameters should be prefixed with underscores (e.g., _a, _b, _d, _f) to indicate they're intentionally declared for type demonstration purposes while still allowing the stricter lint rules to catch genuine issues.

Apply this diff to remove the suppression and prefix the unused parameters:

-/* eslint-disable @typescript-eslint/no-unused-vars */
 import React from 'react';
 
 type PropTypes = { a?: string; b: string };
 
-export const ControlsParameters = ({ a = 'a', b }: PropTypes) => <div>Example story</div>;
+export const ControlsParameters = ({ a: _a = 'a', b: _b }: PropTypes) => <div>Example story</div>;
 
 type SubcomponentAPropTypes = { e: boolean; c: boolean; d?: boolean };
 
-export const SubcomponentA = ({ d = false }: SubcomponentAPropTypes) => (
+export const SubcomponentA = ({ d: _d = false }: SubcomponentAPropTypes) => (
   <div>Example subcomponent A</div>
 );
 
 type SubcomponentBPropTypes = { g: number; h: number; f?: number };
 
-export const SubcomponentB = ({ f = 42 }: SubcomponentBPropTypes) => (
+export const SubcomponentB = ({ f: _f = 42 }: SubcomponentBPropTypes) => (
   <div>Example subcomponent B</div>
 );
🧹 Nitpick comments (5)
code/core/src/common/js-package-manager/Yarn1Proxy.test.ts (1)

99-107: LGTM! Unused parameter correctly removed.

The change to a no-argument mock implementation is correct—the mock returns a fixed object and doesn't need any parameters. This aligns with the PR's goal of applying stricter ESLint rules for unused variables.

Optional: Consider moving mock implementations to beforeEach.

Per coding guidelines, mock behaviors should be implemented in beforeEach blocks rather than inline within test cases. This applies to mocks throughout the file (lines 99, 172, etc.). While this is a pre-existing pattern and not introduced by this PR, consolidating mocks in beforeEach would improve consistency and maintainability.

Based on learnings and coding guidelines.

code/core/src/core-server/presets/favicon.test.ts (1)

57-67: Consider using spy: true for package mocks.

Per coding guidelines, package mocks should use vi.mock() with the spy: true option. This would allow the original implementations to be spied on while still allowing test-specific overrides.

Apply this pattern:

-vi.mock('node:fs', async (importOriginal) => ({
-  ...(await importOriginal<typeof import('node:fs')>()),
+vi.mock('node:fs', { spy: true }, async (importOriginal) => ({
   existsSync: vi.fn(() => {
     return false;
   }),
   statSync: vi.fn(() => {
     return {
       isFile: () => false,
     };
   }),
 }));

Note: This is a pre-existing pattern; the current PR changes are appropriate for their scope. Based on learnings.

code/frameworks/nextjs/src/swc/next-swc-loader-patch.ts (1)

137-137: Consider updating for consistency (optional).

This line still passes a name parameter to traceChild, but the mock at line 51 no longer accepts parameters. While this works fine at runtime (JavaScript ignores extra arguments, and parentTrace is typed as any), updating this call to parentTrace.traceChild() would improve consistency across the mock's usage.

Apply this diff if you'd like to align with the parameterless signature:

-  const swcSpan = parentTrace.traceChild('next-swc-transform');
+  const swcSpan = parentTrace.traceChild();
code/core/src/core-server/utils/save-story/mocks/export-variances.stories.tsx (1)

17-19: Clarify whether unused props are intentional test fixtures.

The component signature includes absolute and bordered props that are never provided in any story args. If these props serve a testing purpose (e.g., verifying the system handles components with extra props), consider adding a comment. Otherwise, they should be removed to align with the stricter unused vars rules.

Apply this diff if the unused props serve no testing purpose:

-const MyComponent: FC<{ absolute: boolean; bordered: boolean; initial: string }> = (props) => (
+const MyComponent: FC<{ initial: string }> = (props) => (
   <pre>{JSON.stringify(props)}</pre>
 );
code/core/src/core-server/utils/save-story/mocks/typescript-constructs.stories.tsx (1)

17-19: Remove unused props or document their testing purpose.

The absolute and bordered props are unused in all stories. Since this file focuses on testing TypeScript type constructs (as, satisfies, etc.) rather than prop handling, these unused props appear unnecessary.

Apply this diff if the unused props serve no testing purpose:

-const MyComponent: FC<{ absolute: boolean; bordered: boolean; initial: string }> = (props) => (
+const MyComponent: FC<{ initial: string }> = (props) => (
   <pre>{JSON.stringify(props)}</pre>
 );

@valentinpalkovic valentinpalkovic force-pushed the valentin/apply-stricter-unused-var-eslint-rules branch from 44dc6e2 to 1fe3404 Compare November 11, 2025 12:09
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
code/frameworks/angular/template/stories/basics/angular-forms/customControlValueAccessor/custom-cva-component.stories.ts (1)

15-19: Replace console.log with Storybook logger or remove debug decorator.

This decorator uses console.log, which violates the coding guidelines for this repository. According to the guidelines, application code under code/** should use Storybook loggers instead of console.* methods.

If this decorator is intended for debugging purposes and should remain, use the Storybook client logger instead:

+import { logger } from 'storybook/internal/client-logger';
+
 const meta: Meta<CustomCvaComponent> = {
   // title: 'Basics / Angular forms / ControlValueAccessor',
   component: CustomCvaComponent,
   decorators: [
     moduleMetadata({
       imports: [FormsModule],
     }),
     (storyFn) => {
       const story = storyFn();
-      console.log(story);
+      logger.log(story);
       return story;
     },
   ],
 } as Meta;

Alternatively, if this decorator was added for debugging and is no longer needed, consider removing it entirely.

As per coding guidelines

♻️ Duplicate comments (2)
code/addons/docs/src/blocks/examples/ControlsParameters.tsx (1)

1-1: Suppressing unused-vars warnings contradicts the PR objective.

The PR aims to apply stricter ESLint rules for unused variables, yet this change adds an eslint-disable directive instead of addressing the unused parameters. According to the AI summary, other files in this PR use underscore-prefixing for unused parameters—this file should follow that same pattern for consistency. Since this is an example file for documentation, it should model best practices rather than suppress linting rules.

Apply this diff to align with the PR's pattern and remove the suppression:

-/* eslint-disable @typescript-eslint/no-unused-vars */
 import React from 'react';
 
 type PropTypes = { a?: string; b: string };
 
-export const ControlsParameters = ({ a = 'a', b }: PropTypes) => <div>Example story</div>;
+export const ControlsParameters = ({ a: _a = 'a', b: _b }: PropTypes) => <div>Example story</div>;
 
 type SubcomponentAPropTypes = { e: boolean; c: boolean; d?: boolean };
 
-export const SubcomponentA = ({ d = false }: SubcomponentAPropTypes) => (
+export const SubcomponentA = ({ d: _d = false }: SubcomponentAPropTypes) => (
   <div>Example subcomponent A</div>
 );
 
 type SubcomponentBPropTypes = { g: number; h: number; f?: number };
 
-export const SubcomponentB = ({ f = 42 }: SubcomponentBPropTypes) => (
+export const SubcomponentB = ({ f: _f = 42 }: SubcomponentBPropTypes) => (
   <div>Example subcomponent B</div>
 );
code/core/src/csf/csf-factories.test.ts (1)

1-1: Reconsider file-level disable of no-unused-vars rule.

Adding a file-level eslint-disable contradicts the PR objective of applying stricter unused variable rules. Instead of disabling the rule for the entire file, address specific unused variables by:

  1. Prefixing intentionally unused parameters with underscore (e.g., _args)
  2. Removing genuinely unused variables
  3. Keeping type parameters needed for type checking (expected behavior)

Apply this approach throughout the file:

-/* eslint-disable @typescript-eslint/no-unused-vars */
 //* @vitest-environment happy-dom */

Then audit the file for actual unused variables and prefix any intentionally unused function parameters with _.

🧹 Nitpick comments (1)
code/core/src/types/modules/addons.ts (1)

157-157: Consider using type alias for empty interface.

The underscore prefix on _StoryFnReturnType appropriately documents the unused generic parameter. However, the empty interface body can be replaced with a type alias for better semantics.

Apply this diff:

-export interface Addon_ClientStoryApi<_StoryFnReturnType = unknown> {}
+export type Addon_ClientStoryApi<_StoryFnReturnType = unknown> = Record<string, never>;

Or if this serves as an extension point:

-export interface Addon_ClientStoryApi<_StoryFnReturnType = unknown> {}
+// eslint-disable-next-line @typescript-eslint/no-empty-object-type
+export interface Addon_ClientStoryApi<_StoryFnReturnType = unknown> {}

Comment on lines +61 to +62
name="bar"
title="foo"
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

🧩 Analysis chain

Verify that forwarding title and name to the DOM anchor is intentional.

The updated snapshot shows that title and name props are now being rendered as HTML attributes on the anchor element. These props appear to be Storybook-specific identifiers (used in the SELECT_STORY event at lines 96-97), not necessarily attributes meant for the DOM:

  1. The name attribute on <a> elements is deprecated in HTML5 (replaced by id)
  2. Forwarding internal Storybook identifiers (title, name) to the DOM may pollute the HTML with unnecessary attributes

This change appears to be a side effect of the ESLint unused variable fix—if title and name were previously destructured to prevent forwarding, removing that destructuring would cause them to spread onto the DOM element.

If this forwarding is unintentional, consider explicitly destructuring these props in link.tsx to exclude them from the rest spread:

const { title, name, ...restProps } = props;
// Use title and name for story selection only
// Spread only restProps onto the anchor element

Alternatively, prefix them with an underscore in the destructuring if they're intentionally unused in that scope:

const { title: _title, name: _name, ...restProps } = props;

🏁 Script executed:

#!/bin/bash
# Locate and inspect the LinkTo component implementation in link.tsx
find . -name "link.tsx" -type f | head -5

Length of output: 112


🏁 Script executed:

#!/bin/bash
# Inspect the test file to understand context around lines 47, 61-62, and 96-97
cat code/addons/links/src/react/components/link.test.tsx | head -110

Length of output: 2353


🏁 Script executed:

#!/bin/bash
# Search for how props are destructured/spread in the LinkTo component
rg -n "title|name" code/addons/links/src/react/components/link.tsx -A 2 -B 2

Length of output: 873


🏁 Script executed:

#!/bin/bash
# Get the full link.tsx component to see the render method
cat code/addons/links/src/react/components/link.tsx

Length of output: 2074


Destructure title and name in the render method to prevent them from spreading onto the DOM anchor element.

The analysis confirms the review comment is accurate. In code/addons/links/src/react/components/link.tsx, the render() method destructures { kind, story, children, ...rest } but does NOT explicitly extract title and name. This causes them to be included in the ...rest spread onto the anchor element, polluting the DOM with Storybook-internal identifiers.

The name attribute on <a> elements is deprecated in HTML5 and these properties are meant only for story identification in event emissions—not DOM attributes.

Fix by explicitly destructuring title and name in link.tsx line 79:

const { kind, story, title, name, children, ...rest } = this.props;

This prevents them from being included in ...rest and spreading to the anchor, consistent with how kind and story are already handled. The test snapshot at lines 61–62 will need to be updated to remove the name and title attributes from the expected anchor output.

🤖 Prompt for AI Agents
In code/addons/links/src/react/components/link.tsx around line 79 and the test
file code/addons/links/src/react/components/link.test.tsx around lines 61–62,
explicitly destructure title and name from this.props in the render method
(e.g., include title and name alongside kind and story) so they are not included
in ...rest and thus not spread onto the anchor element; then update the test
snapshot/expected output in link.test.tsx to remove the now-absent title and
name attributes from the anchor.

Comment on lines +1 to +2
/* eslint-disable @typescript-eslint/no-unused-vars */

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 | 🟠 Major

Reconsider file-level disable of no-unused-vars rule.

Adding a file-level eslint-disable contradicts the PR objective of applying stricter unused variable rules. Instead of disabling the rule for the entire file, address specific unused variables by:

  1. Prefixing intentionally unused parameters with underscore (e.g., _context)
  2. Removing genuinely unused variables
  3. Keeping type parameters needed for type checking (expected behavior)

Apply this approach throughout the file:

-/* eslint-disable @typescript-eslint/no-unused-vars */
-
 /* global HTMLElement */

Then audit the file for actual unused variables and prefix any intentionally unused function parameters with _.

📝 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
/* eslint-disable @typescript-eslint/no-unused-vars */
/* global HTMLElement */
🤖 Prompt for AI Agents
In code/core/src/csf/story.test.ts around lines 1 to 2, remove the file-level
eslint-disable for @typescript-eslint/no-unused-vars and instead handle unused
identifiers locally: delete any truly unused variables, rename intentionally
unused function parameters by prefixing them with an underscore (e.g.,
_context), and retain type-only generics or type imports required for type
checking; audit the rest of the file and apply the same pattern so only needed
identifiers remain and intentional unused params use the underscore prefix.

@@ -1,5 +1,3 @@
import React from 'react';
Copy link
Member

Choose a reason for hiding this comment

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

We can't do this yet.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Please add some elaboration for future reference.

Copy link
Member

Choose a reason for hiding this comment

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

Due to the way we build our code & how manager-builder is configured.
It was setup in the days before the jsx-runtime was a thing, and has has not been changed since.

};

addons.register(ADDON_ID, (api) => {
addons.register(ADDON_ID, (_api) => {
Copy link
Member

Choose a reason for hiding this comment

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

I personally do not see how this improves things.
TS already warns about unused vars, and they get compiled away at build-time.

I'd be pretty unhappy about unused vars getting removed automatically, unless they start with a _-character, since I often work on new functions and consts first, then the usage.

Copy link
Contributor Author

@valentinpalkovic valentinpalkovic Nov 12, 2025

Choose a reason for hiding this comment

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

I'd be pretty unhappy about unused vars getting removed automatically, unless they start with a _-character, since I often work on new functions and consts first, then the usage.

You don't have to worry about this. Unused args aren't removed automatically. They are just marked as errors. You still have to remove them manually. That's pretty handy because we are forced to consider whether a particular argument is necessary or whether we want to keep it for the function signature.

You're right that TypeScript already warns about that in your IDE, but you don't have that warning during code reviews. It is not evident to the reviewer at first glance whether a variable/argument is used or not. Using an underscore notation improves the readability.

@ndelangen ndelangen self-requested a review November 14, 2025 07:35
@github-actions github-actions bot added the Stale label Nov 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:daily Run the CI jobs that normally run in the daily job. maintenance User-facing maintenance tasks Stale

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants