Skip to content

feat(linters): add eslint-plugin-spectrum-wc to the monorepo#6361

Draft
Rajdeepc wants to merge 4 commits into
mainfrom
rajdeepchandra/feat-eslint-plugin-spectrum-wc
Draft

feat(linters): add eslint-plugin-spectrum-wc to the monorepo#6361
Rajdeepc wants to merge 4 commits into
mainfrom
rajdeepchandra/feat-eslint-plugin-spectrum-wc

Conversation

@Rajdeepc

@Rajdeepc Rajdeepc commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Description

Integrates the consumer-facing eslint-plugin-spectrum-wc ESLint plugin into the monorepo so it can be versioned, tested, and released alongside the component library. The plugin catches accessibility gaps, deprecated APIs, invalid attribute values, and slot misuse at lint time for both Lit `html`` tagged templates and JSX/TSX — shifting left what `window.__swc.warn()` and axe catch at runtime.

Previously maintained as a standalone repo at Rajdeepc/eslint-plugin-spectrum-wc, this PR brings the plugin home so that component descriptor updates and rule improvements ship in lockstep with the components themselves.

Motivation and context

SWC consumers currently discover accessibility gaps, deprecated APIs (e.g. `variant="cta"` on ``), and invalid slot usage only at runtime through browser warnings or axe audits. An ESLint plugin shifts these checks to the editor and CI, providing immediate feedback during development. Hosting it in the monorepo ensures:

  • Descriptor accuracy: component metadata stays in sync with actual component changes
  • Unified release pipeline: changesets handle versioning and npm publish
  • Single CI gate: tests run alongside the rest of the monorepo

Architecture

The plugin is data-driven. Six rules are generated from a central component descriptor map (`src/descriptors/components.ts`), so adding a new component requires zero rule code:

```
linters/eslint-plugin-spectrum-wc/
├── src/
│ ├── adapters/ # Lit html`` + JSX/TSX template parsers
│ ├── core/ # Types + rule factory (generates rules from descriptors)
│ ├── descriptors/ # Component a11y, deprecation, slot, and attribute metadata
│ ├── rules/ # 6 thin wrappers: factory(descriptors)
│ └── index.ts # Plugin entry with recommended + strict configs
└── tests/ # 13 test files, 187 tests (Lit + JSX coverage)
```

Rules included

Rule Purpose
`swc/accessible-component` Require accessibility attributes (label, aria-label, etc.) on SWC elements
`swc/no-deprecated` Flag deprecated attributes and attribute values
`swc/required-attributes` Enforce presence of configuration attributes (e.g. `color`, `scale` on ``)
`swc/valid-attribute-values` Catch invalid enum values at lint time
`swc/valid-slot-names` Warn when children target non-existent slots
`swc/valid-slot-children` Warn when a child tag is not accepted in a slot

Integration decisions

Decision Rationale
Location: `linters/eslint-plugin-spectrum-wc/` Follows existing `linters/*` workspace pattern
Package name: `eslint-plugin-spectrum-wc` (unscoped) Consumer-facing npm package; ESLint plugin naming convention
Not private Published to npm (unlike the internal `@spectrum-web-components/eslint-plugin`)
Independent versioning Outside the `@spectrum-web-components/*` fixed changeset group
TypeScript + vitest Matches original plugin tooling; vitest already in the monorepo

Related issue(s)

Author's checklist

  • I have read the CONTRIBUTING and PULL_REQUESTS documents.
  • I have reviewed at the Accessibility Practices for this feature, see: Aria Practices
  • I have added automated tests to cover my changes.
  • I have included a well-written changeset if my change needs to be published.
  • I have included updated documentation if my change required it.

Reviewer's checklist

  • Includes a Github Issue with appropriate flag or Jira ticket number without a link
  • Includes thoughtfully written changeset if changes suggested include `patch`, `minor`, or `major` features
  • Automated tests cover all use cases and follow best practices for writing
  • Validated on all supported browsers
  • All VRTs are approved before the author can update Golden Hash

Manual review test cases

  • Verify build passes

    1. `cd linters/eslint-plugin-spectrum-wc`
    2. `yarn build`
    3. Expect zero TypeScript errors, `dist/` directory created with `.js`, `.d.ts`, and `.js.map` files
  • Verify all 187 tests pass

    1. `cd linters/eslint-plugin-spectrum-wc`
    2. `yarn test`
    3. Expect 13 test files, 187 tests, all green
  • Verify workspace registration

    1. `yarn workspaces list | grep eslint-plugin-spectrum-wc`
    2. Expect the package appears in the workspace list
  • Verify the plugin loads in an ESLint flat config

    1. Create a temp `eslint.config.js` that imports `eslint-plugin-spectrum-wc` and uses `swc.configs.recommended`
    2. Run ESLint on a file with ``html\`Click\```
    3. Expect `swc/no-deprecated` warning about the `cta` variant

Device review

  • Did it pass in Desktop? (N/A — linter package, no UI)
  • Did it pass in (emulated) Mobile? (N/A — linter package, no UI)
  • Did it pass in (emulated) iPad? (N/A — linter package, no UI)

Accessibility testing checklist

  • Keyboard — N/A: this is a developer tooling package (ESLint plugin), not a UI component. It has no interactive elements or focus management. The plugin enforces keyboard accessibility in consumer code via the `swc/accessible-component` rule.

  • Screen reader — N/A: same rationale as above. The plugin enforces screen reader accessibility by requiring `label`, `aria-label`, or `aria-labelledby` attributes on SWC elements.

- integrate the consumer-facing ESLint plugin that catches accessibility
gaps, deprecated APIs, invalid attribute values, and slot misuse at lint
time for both Lit html`` templates and JSX/TSX
- the plugin is data-driven: six rules are generated from a central
component descriptor map so adding a new component requires zero rule code
- placed in linters/eslint-plugin-spectrum-wc following the existing
linters/* workspace convention alongside the internal eslint-plugin
- published as the unscoped eslint-plugin-spectrum-wc package with
independent versioning (outside the @spectrum-web-components fixed group)
- 187 tests across 13 files cover Lit and JSX adapters plus all rules

Rules included:
  swc/accessible-component
  swc/no-deprecated
  swc/required-attributes
  swc/valid-attribute-values
  swc/valid-slot-names
  swc/valid-slot-children

Co-authored-by: Cursor <cursoragent@cursor.com>
@Rajdeepc Rajdeepc requested a review from a team as a code owner June 2, 2026 11:08
@Rajdeepc Rajdeepc added the Feature New feature or request label Jun 2, 2026
@changeset-bot

changeset-bot Bot commented Jun 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 7972e5d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
eslint-plugin-spectrum-wc Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@Rajdeepc Rajdeepc self-assigned this Jun 2, 2026
@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

📚 Branch Preview Links

🔍 First Generation Visual Regression Test Results

When a visual regression test fails (or has previously failed while working on this branch), its results can be found in the following URLs:

Deployed to Azure Blob Storage: pr-6361

If the changes are expected, update the current_golden_images_cache hash in the circleci config to accept the new images. Instructions are included in that file.
If the changes are unexpected, you can investigate the cause of the differences and update the code accordingly.

…elease

Co-authored-by: Cursor <cursoragent@cursor.com>
@Rajdeepc Rajdeepc requested a review from AlexHayton June 2, 2026 11:48
Rajdeep Chandra and others added 2 commits June 2, 2026 17:45
…/tools

- relocate from linters/ to 2nd-gen/packages/tools/ to co-locate with
other 2nd-gen tooling packages (postcss-token, swc-tokens, etc.)
- update repository.directory and rule doc URLs to reflect the new path
- build and all 187 tests pass in the new location

Co-authored-by: Cursor <cursoragent@cursor.com>
Rajdeepc

This comment was marked as outdated.

@Rajdeepc Rajdeepc marked this pull request as draft June 9, 2026 07:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant