Skip to content

chore(internals): add new rules for class inheritance and aria attribute management#92

Merged
coryrylan merged 2 commits into
mainfrom
topic-internal-lint
May 18, 2026
Merged

chore(internals): add new rules for class inheritance and aria attribute management#92
coryrylan merged 2 commits into
mainfrom
topic-internal-lint

Conversation

@coryrylan
Copy link
Copy Markdown
Collaborator

@coryrylan coryrylan commented May 18, 2026

Summary by CodeRabbit

  • New Features

    • Media docs fully integrated into component docs, search metadata, and examples permalinks; site build now pulls media outputs.
    • Examples listing now filters by SSR-capable entrypoints so only compatible examples show.
  • Chores

    • Coverage badges now show formatted percentages or “unknown” when coverage is not a finite number.
  • Chores / Maintenance

    • New linting rules and accompanying tests added to improve code quality and guard class/ARIA patterns.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 18, 2026

📝 Walkthrough

Walkthrough

Adds three new ESLint rules and registers them in configs; integrates @nvidia-elements/media into site build/docs (globs, devDependency, permalinks), refines coverage badge logic, and filters examples by SSR-capable entrypoints.

Changes

Media package integration and ESLint infrastructure

Layer / File(s) Summary
ESLint rule: no-deep-class-inheritance
projects/internals/eslint/src/local/no-deep-class-inheritance.js, projects/internals/eslint/src/local/no-deep-class-inheritance.test.js, projects/internals/eslint/README.md
Adds rule enforcing maximum class inheritance depth (default 2) with configurable allowedRoots; implements TS-symbol chain walking, helpers, README entry, and tests for valid/invalid chains.
ESLint rule: no-host-managed-aria-attributes
projects/internals/eslint/src/local/no-host-managed-aria-attributes.js, projects/internals/eslint/src/local/no-host-managed-aria-attributes.test.js
Adds rule flagging host setAttribute/removeAttribute/toggleAttribute calls targeting managed ARIA/role attributes with static string args; reports mapped controller and method; includes helpers and tests.
ESLint rule: no-single-consumer-internal-base
projects/internals/eslint/src/local/no-single-consumer-internal-base.js, projects/internals/eslint/src/local/no-single-consumer-internal-base.test.js
Adds rule preventing exported internal base classes with fewer than minimumConsumers (default 2); counts local and cross-file subclasses via AST and import/regex scanning, supports barrel detection and caching, and includes multi-scenario tests.
ESLint rules configuration and registration
projects/internals/eslint/src/configs/lit.js, projects/internals/eslint/src/configs/typescript.js
Imports and registers the new local rules, adds them to plugin rule maps, and enables them with error severity and configured options (maxDepth, allowedRoots, minimumConsumers).
Media package site integration
knip.config.js, projects/site/eleventy.config.js, projects/site/package.json, projects/site/src/_11ty/layouts/docs.11ty.js, projects/site/src/_11ty/templates/api.js, projects/site/src/docs/elements/_tabs/examples.11ty.js
Adds @nvidia-elements/media to knip ignore, includes media markdown in componentDocs, wires ../media build artifacts and adds devDependency, maps /docs/media/ to elements section, updates examples permalinks for media paths, and replaces broad coverage selection with a helper that may return undefined.
SSR entrypoint filtering for examples
projects/starters/eleventy-ssr/src/index.11ty.js
Adds SSR-capable package prefix detection and filters example card generation to include only elements whose manifest entrypoint matches those prefixes.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • NVIDIA/elements#75: Extends knip configuration; both PRs modify knip.config.js for dependency management of @nvidia-elements packages.
  • NVIDIA/elements#27: Modifies ESLint TypeScript config; related to enabling/configuring TypeScript lint rules.

Suggested labels

scope(lint)

Suggested reviewers

  • johnyanarella
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding two new ESLint rules (no-deep-class-inheritance and no-host-managed-aria-attributes) for managing class inheritance depth and ARIA attribute handling.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch topic-internal-lint

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

@coryrylan coryrylan changed the title Topic internal lint chore(internals): add new rules for class inheritance and aria attribute management May 18, 2026
Copy link
Copy Markdown

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@projects/internals/eslint/src/local/no-single-consumer-internal-base.js`:
- Around line 155-165: The barrel-import resolution breaks on Windows due to
hardcoded '/' handling; update getRelativeJsImport and the caller
isExportedFromInternalBarrel to normalize paths to POSIX-style before slicing or
passing to relative(): compute fromDirectory by first normalizing fromFile (use
normalizePath or replace backslashes) then find lastIndexOf('/'), normalize the
toFile (remove backslash extensions) and ensure the value passed as indexFile
(the result of join()) is normalized with normalizePath so relative() and the
specifier logic produce a proper './...' specifier on all platforms.
- Around line 139-153: The current logic in importsClass and countSubclasses
misses aliased imports (e.g., "import { Base as InternalBase }") so subclasses
extending the local alias are not counted; update the file to first parse import
declarations into a local import map that resolves exported symbol names to
their local identifiers (handle named imports with "as" aliases, default
imports, and namespace imports where applicable) and then change countSubclasses
to test for subclasses extending any of the local identifiers from that map
rather than the original className string (use importsClass or a new helper to
build the map and feed the derived local names into the subclass regex
matching).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 1a5b9b77-59ea-451f-a8b0-474a3f3fef55

📥 Commits

Reviewing files that changed from the base of the PR and between b931ff5 and 672da0b.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (16)
  • knip.config.js
  • projects/internals/eslint/README.md
  • projects/internals/eslint/src/configs/lit.js
  • projects/internals/eslint/src/configs/typescript.js
  • projects/internals/eslint/src/local/no-deep-class-inheritance.js
  • projects/internals/eslint/src/local/no-deep-class-inheritance.test.js
  • projects/internals/eslint/src/local/no-host-managed-aria-attributes.js
  • projects/internals/eslint/src/local/no-host-managed-aria-attributes.test.js
  • projects/internals/eslint/src/local/no-single-consumer-internal-base.js
  • projects/internals/eslint/src/local/no-single-consumer-internal-base.test.js
  • projects/site/eleventy.config.js
  • projects/site/package.json
  • projects/site/src/_11ty/layouts/docs.11ty.js
  • projects/site/src/_11ty/templates/api.js
  • projects/site/src/docs/elements/_tabs/examples.11ty.js
  • projects/starters/eleventy-ssr/src/index.11ty.js

Comment thread projects/internals/eslint/src/local/no-single-consumer-internal-base.js Outdated
@coryrylan coryrylan force-pushed the topic-internal-lint branch from 672da0b to af08c63 Compare May 18, 2026 13:34
Copy link
Copy Markdown

@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)
projects/internals/eslint/src/local/no-single-consumer-internal-base.js (1)

238-241: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Normalize joined filesystem paths before computing relative import specifiers.

Line 239 slices on '/', and Line 273 passes a platform-native join() path into that flow. On Windows, this can generate invalid specifiers and miss consumers.

Suggested fix
-import { dirname, join, relative, sep } from 'node:path';
+import { dirname, join, relative, sep } from 'node:path';
...
 function getRelativeJsImport(fromFile, toFile) {
-  const fromDirectory = fromFile.slice(0, fromFile.lastIndexOf('/'));
-  const withoutExtension = toFile.replace(/\.tsx?$/, '.js');
+  const normalizedFromFile = normalizePath(fromFile);
+  const normalizedToFile = normalizePath(toFile);
+  const fromDirectory = dirname(normalizedFromFile);
+  const withoutExtension = normalizedToFile.replace(/\.tsx?$/, '.js');
   let specifier = normalizePath(relative(fromDirectory, withoutExtension));
...
 function isExportedFromInternalBarrel(rootDir, filename, className) {
-  const indexFile = join(rootDir, 'src/internal/index.ts');
+  const indexFile = normalizePath(join(rootDir, 'src/internal/index.ts'));
   if (!existsSync(indexFile)) {
     return false;
   }

Also applies to: 272-279

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@projects/internals/eslint/src/local/no-single-consumer-internal-base.js`
around lines 238 - 241, The getRelativeJsImport function builds a relative
specifier using paths that may contain platform-specific separators; normalize
both inputs to POSIX-style paths before slicing and joining so Windows
backslashes don't leak into specifiers. Specifically, ensure the fromFile and
toFile (and any usage of join()/relative()) are converted to normalized POSIX
paths (e.g., replace backslashes with '/') before deriving fromDirectory,
computing withoutExtension, and calling normalizePath/relative so the import
specifier is always valid.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@projects/internals/eslint/src/local/no-single-consumer-internal-base.test.js`:
- Around line 275-279: The helper createFile uses string slicing with '/' to
derive the parent directory which breaks on Windows; change it to use Node's
path.dirname (ensure path is imported) to compute the directory and pass that to
mkdirSync with { recursive: true }, e.g. replace filename.slice(0,
filename.lastIndexOf('/')) with path.dirname(filename) inside the createFile
function to make directory creation cross-platform.

---

Duplicate comments:
In `@projects/internals/eslint/src/local/no-single-consumer-internal-base.js`:
- Around line 238-241: The getRelativeJsImport function builds a relative
specifier using paths that may contain platform-specific separators; normalize
both inputs to POSIX-style paths before slicing and joining so Windows
backslashes don't leak into specifiers. Specifically, ensure the fromFile and
toFile (and any usage of join()/relative()) are converted to normalized POSIX
paths (e.g., replace backslashes with '/') before deriving fromDirectory,
computing withoutExtension, and calling normalizePath/relative so the import
specifier is always valid.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 06dfbb52-e343-4cf3-aaea-496aca9c4c64

📥 Commits

Reviewing files that changed from the base of the PR and between 672da0b and af08c63.

📒 Files selected for processing (8)
  • projects/internals/eslint/src/configs/lit.js
  • projects/internals/eslint/src/configs/typescript.js
  • projects/internals/eslint/src/local/no-deep-class-inheritance.js
  • projects/internals/eslint/src/local/no-deep-class-inheritance.test.js
  • projects/internals/eslint/src/local/no-host-managed-aria-attributes.js
  • projects/internals/eslint/src/local/no-host-managed-aria-attributes.test.js
  • projects/internals/eslint/src/local/no-single-consumer-internal-base.js
  • projects/internals/eslint/src/local/no-single-consumer-internal-base.test.js

'local-typescript/no-deep-class-inheritance': [
'error',
{ maxDepth: 2, allowedRoots: ['HTMLElement', 'LitElement', 'FormControlMixin', 'BaseButton'] }
],
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This is to keep agents from wanting to default to large inheritance chains instead of using composition based solutions

'local/require-element-definitions': ['error'],
'local/require-composed-events': ['error'],
'local/no-host-managed-aria-attributes': ['error'],
'local/no-single-consumer-internal-base': ['error'],
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This rule helps prevent agents from creating unnecessary base class abstractions when there is no shared code logic between classes or components.

export default {
meta: {
type: 'problem',
name: 'no-host-managed-aria-attributes',
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This helps prevent agents from using attribute based aria setters instead of leaning out the element internal APIs which provide better element default behavior.

if (section === 'integrations') return 'integrations';
if (section === 'foundations') return 'foundations';
if (section === 'patterns') return 'patterns';
if (section === 'media') return 'elements';
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixing some minor missing infra for the media package and build/docs

coryrylan added 2 commits May 18, 2026 10:40
- Added '@nvidia-elements/media' to the configuration and package.json.
- Updated Eleventy configuration to include public component documentation for media.
- Enhanced example URL generation to support media components.
- Refactored coverage calculation logic in API template for better clarity.
- Updated pnpm lockfile to reflect new dependencies and versions.

Signed-off-by: Cory Rylan <crylan@nvidia.com>
…ute management

- Introduced `no-deep-class-inheritance` rule to limit class inheritance depth, ensuring better maintainability.
- Added `no-host-managed-aria-attributes` rule to prevent misuse of ARIA attributes that should be managed through ElementInternals.
- Implemented `no-single-consumer-internal-base` rule to disallow internal base classes with fewer than two consumers, promoting better design practices.
- Updated ESLint configurations to include the new rules and their respective error handling.

Signed-off-by: Cory Rylan <crylan@nvidia.com>
@coryrylan coryrylan force-pushed the topic-internal-lint branch from af08c63 to 45c25e3 Compare May 18, 2026 15:40
@coryrylan coryrylan enabled auto-merge (rebase) May 18, 2026 15:40
@coryrylan coryrylan disabled auto-merge May 18, 2026 15:45
Copy link
Copy Markdown

@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 (2)
projects/internals/eslint/src/local/no-single-consumer-internal-base.test.js (1)

5-5: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use path.dirname for parent-directory creation.

Line 277 derives the directory using '/' slicing, which breaks on Windows path separators and can fail temp file setup.

Suggested fix
-import { join } from 'node:path';
+import { dirname, join } from 'node:path';
@@
 function createFile(relativePath, content) {
   const filename = join(rootDir, relativePath);
-  mkdirSync(filename.slice(0, filename.lastIndexOf('/')), { recursive: true });
+  mkdirSync(dirname(filename), { recursive: true });
   writeFileSync(filename, content);
   return filename;
 }
#!/bin/bash
# Verify the non-portable pattern exists
rg -n "filename\.slice\(0, filename\.lastIndexOf\('/'\)\)" projects/internals/eslint/src/local/no-single-consumer-internal-base.test.js

# Demonstrate why '/' slicing fails for Windows-style paths
python - <<'PY'
from pathlib import PureWindowsPath
filename = str(PureWindowsPath(r"C:\repo\src\internal\media-button.ts"))
sliced_parent = filename[:filename.rfind('/')]
print("filename:", filename)
print("sliced_parent:", repr(sliced_parent))
print("expected_parent:", str(PureWindowsPath(filename).parent))
PY

Also applies to: 275-279

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@projects/internals/eslint/src/local/no-single-consumer-internal-base.test.js`
at line 5, The test constructs a parent directory by slicing the string filename
with '/' which is not cross-platform; replace the manual slice (occurrences of
filename.slice(0, filename.lastIndexOf('/')) and any similar uses around the
filename variable) with a proper path dirname call (e.g., path.dirname(filename)
or import { dirname } from 'path' and use dirname(filename)) so Windows
backslashes are handled correctly and temp file setup becomes portable; update
any related uses in the same block (lines ~275-279) to use the dirname-based
approach and remove the brittle string slicing.
projects/internals/eslint/src/local/no-single-consumer-internal-base.js (1)

238-241: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Normalize path inputs before computing relative JS import specifiers.

Line 239 assumes '/' separators. Combined with Line 273 (join(...)) on Windows, barrel resolution can generate bad specifiers and undercount consumers.

Suggested fix
 function getRelativeJsImport(fromFile, toFile) {
-  const fromDirectory = fromFile.slice(0, fromFile.lastIndexOf('/'));
-  const withoutExtension = toFile.replace(/\.tsx?$/, '.js');
+  const normalizedFrom = normalizePath(fromFile);
+  const normalizedTo = normalizePath(toFile);
+  const fromDirectory = dirname(normalizedFrom);
+  const withoutExtension = normalizedTo.replace(/\.tsx?$/, '.js');
   let specifier = normalizePath(relative(fromDirectory, withoutExtension));
@@
 function isExportedFromInternalBarrel(rootDir, filename, className) {
-  const indexFile = join(rootDir, 'src/internal/index.ts');
+  const indexFile = normalizePath(join(rootDir, 'src/internal/index.ts'));
   if (!existsSync(indexFile)) {
     return false;
   }
#!/bin/bash
# Show the relevant code locations
rg -n "function getRelativeJsImport|fromFile\.slice|isExportedFromInternalBarrel|const indexFile = join" projects/internals/eslint/src/local/no-single-consumer-internal-base.js

# Demonstrate separator assumption failure
python - <<'PY'
from pathlib import PureWindowsPath
from_file = str(PureWindowsPath(r"C:\repo\pkg\src\internal\index.ts"))
print("from_file:", from_file)
print("lastIndexOf('/') equivalent:", from_file.rfind('/'))
print("derived_from_directory_with_slice:", repr(from_file[:from_file.rfind('/')]))
PY

Also applies to: 273-279

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@projects/internals/eslint/src/local/no-single-consumer-internal-base.js`
around lines 238 - 241, getRelativeJsImport assumes POSIX separators by slicing
fromFile with '/' and later uses join(...) (see indexFile and
isExportedFromInternalBarrel usage), which breaks on Windows; before deriving
fromDirectory and before calling relative/normalizePath, normalize both fromFile
and toFile to use POSIX-style separators (e.g. convert backslashes to '/') or
use path.dirname/path.posix functions so normalizePath(relative(...)) receives
consistent separators; update references in getRelativeJsImport and the related
barrel-resolution code paths (indexFile, isExportedFromInternalBarrel) to
operate on the normalized paths.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@projects/internals/eslint/README.md`:
- Line 77: The README's ESLint rules catalog is missing entries for the two
newly registered rules; add concise entries for no-host-managed-aria-attributes
and no-single-consumer-internal-base to the README: document
no-host-managed-aria-attributes under the "Component API shape" section
(describe that it forbids components from managing ARIA attributes on host that
should be managed by consumers) and document no-single-consumer-internal-base
under "Source hygiene" (describe that it prevents creating internal base classes
that are intended for a single consumer), and ensure the rule names match the
registrations in src/configs/lit.js so readers can locate them.

---

Duplicate comments:
In `@projects/internals/eslint/src/local/no-single-consumer-internal-base.js`:
- Around line 238-241: getRelativeJsImport assumes POSIX separators by slicing
fromFile with '/' and later uses join(...) (see indexFile and
isExportedFromInternalBarrel usage), which breaks on Windows; before deriving
fromDirectory and before calling relative/normalizePath, normalize both fromFile
and toFile to use POSIX-style separators (e.g. convert backslashes to '/') or
use path.dirname/path.posix functions so normalizePath(relative(...)) receives
consistent separators; update references in getRelativeJsImport and the related
barrel-resolution code paths (indexFile, isExportedFromInternalBarrel) to
operate on the normalized paths.

In
`@projects/internals/eslint/src/local/no-single-consumer-internal-base.test.js`:
- Line 5: The test constructs a parent directory by slicing the string filename
with '/' which is not cross-platform; replace the manual slice (occurrences of
filename.slice(0, filename.lastIndexOf('/')) and any similar uses around the
filename variable) with a proper path dirname call (e.g., path.dirname(filename)
or import { dirname } from 'path' and use dirname(filename)) so Windows
backslashes are handled correctly and temp file setup becomes portable; update
any related uses in the same block (lines ~275-279) to use the dirname-based
approach and remove the brittle string slicing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: b5a1ad67-242c-4b9a-b0cc-7b429d59aca6

📥 Commits

Reviewing files that changed from the base of the PR and between af08c63 and 45c25e3.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (16)
  • knip.config.js
  • projects/internals/eslint/README.md
  • projects/internals/eslint/src/configs/lit.js
  • projects/internals/eslint/src/configs/typescript.js
  • projects/internals/eslint/src/local/no-deep-class-inheritance.js
  • projects/internals/eslint/src/local/no-deep-class-inheritance.test.js
  • projects/internals/eslint/src/local/no-host-managed-aria-attributes.js
  • projects/internals/eslint/src/local/no-host-managed-aria-attributes.test.js
  • projects/internals/eslint/src/local/no-single-consumer-internal-base.js
  • projects/internals/eslint/src/local/no-single-consumer-internal-base.test.js
  • projects/site/eleventy.config.js
  • projects/site/package.json
  • projects/site/src/_11ty/layouts/docs.11ty.js
  • projects/site/src/_11ty/templates/api.js
  • projects/site/src/docs/elements/_tabs/examples.11ty.js
  • projects/starters/eleventy-ssr/src/index.11ty.js

**Source hygiene**

- **`no-dead-code`**. Flags commented-out imports, exports, declarations, control-flow, and test blocks. The project currently sets this to `warn` during cleanup.
- **`no-deep-class-inheritance`**. Limits class inheritance chains to two superclass hops by default, stopping at configured `allowedRoots` such as `HTMLElement` and `LitElement`.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Document the other two new rules.

The PR adds three new rules (no-deep-class-inheritance, no-host-managed-aria-attributes, and no-single-consumer-internal-base), but the README only documents no-deep-class-inheritance. The other two rules are registered in src/configs/lit.js but are missing from this catalog.

Please add entries for:

  • no-host-managed-aria-attributes (likely under "Component API shape")
  • no-single-consumer-internal-base (likely under "Source hygiene")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@projects/internals/eslint/README.md` at line 77, The README's ESLint rules
catalog is missing entries for the two newly registered rules; add concise
entries for no-host-managed-aria-attributes and no-single-consumer-internal-base
to the README: document no-host-managed-aria-attributes under the "Component API
shape" section (describe that it forbids components from managing ARIA
attributes on host that should be managed by consumers) and document
no-single-consumer-internal-base under "Source hygiene" (describe that it
prevents creating internal base classes that are intended for a single
consumer), and ensure the rule names match the registrations in
src/configs/lit.js so readers can locate them.

@coryrylan coryrylan merged commit c25838a into main May 18, 2026
8 checks passed
@coryrylan coryrylan deleted the topic-internal-lint branch May 18, 2026 15:57
@coryrylan
Copy link
Copy Markdown
Collaborator Author

🎉 This issue has been resolved in version 0.0.11 🎉

Changelog

@coryrylan
Copy link
Copy Markdown
Collaborator Author

🎉 This issue has been resolved in version 0.1.2 🎉

Changelog

@coryrylan
Copy link
Copy Markdown
Collaborator Author

🎉 This issue has been resolved in version 0.2.0 🎉

Changelog

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants