Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 23, 2026


Summary: This PR adds a new ESLint rule namespace-spacing-utils that enforces namespacing of Primer CSS spacing utility classes (margin/padding) with the pr- prefix.

The rule:

  • Detects margin classes like m-4, mx-2, my-3, mt-1, etc.
  • Detects padding classes like p-4, px-2, py-3, pt-1, etc.
  • Handles negative spacing values like m-n4, mt-n2
  • Handles auto values like m-auto, mx-auto
  • Handles responsive variants like mx-sm-2, mx-md-4, p-lg-3 (Primer CSS format)
  • Provides autofix to add the pr- prefix automatically

Example transformations:

  • m-4pr-m-4
  • p-2pr-p-2
  • mx-md-4pr-mx-md-4

@changeset-bot
Copy link

changeset-bot bot commented Jan 23, 2026

⚠️ No Changeset found

Latest commit: aa07187

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

Copilot AI and others added 3 commits January 23, 2026 09:06
Co-authored-by: siddharthkp <1863771+siddharthkp@users.noreply.github.com>
Co-authored-by: siddharthkp <1863771+siddharthkp@users.noreply.github.com>
Co-authored-by: siddharthkp <1863771+siddharthkp@users.noreply.github.com>
Copilot AI changed the title [WIP] Add namespace for primer-css margin and padding utilities Add namespace-spacing-utils rule Jan 23, 2026
Copilot AI requested a review from siddharthkp January 23, 2026 09:11
'<div className={`pr-m-4 pr-p-2`} />',

// Responsive variants (already namespaced)
'<div className="md:pr-m-4" />',
Copy link
Member

Choose a reason for hiding this comment

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

@copilot This is the responsive format: .mx-sm-2 and .mx-md-4

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in aa07187. Updated the regex pattern and tests to use the Primer CSS responsive format (mx-sm-2, mx-md-4, etc.) instead of the colon-separated format.

Co-authored-by: siddharthkp <1863771+siddharthkp@users.noreply.github.com>
Copilot AI requested a review from siddharthkp January 23, 2026 09:31
@siddharthkp siddharthkp marked this pull request as ready for review January 23, 2026 12:57
@siddharthkp siddharthkp requested a review from a team as a code owner January 23, 2026 12:57
Copilot AI review requested due to automatic review settings January 23, 2026 12:57
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a new ESLint rule (namespace-spacing-utils) to enforce pr- namespacing for Primer CSS spacing utility classes (margin/padding), including responsive and negative/auto variants, with autofix support.

Changes:

  • Added the namespace-spacing-utils rule implementation for detecting un-namespaced spacing utility classes in className.
  • Added a comprehensive RuleTester suite for valid/invalid cases and autofix expectations.
  • Added rule documentation and exported the rule from the plugin entrypoint.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.

File Description
src/rules/namespace-spacing-utils.js Implements detection + autofix for un-namespaced spacing utility classes.
src/rules/tests/namespace-spacing-utils.test.js Adds test coverage for detection and fixes across many spacing patterns.
src/index.js Registers the new rule in the plugin’s exported rules map.
docs/rules/namespace-spacing-utils.md Documents the rule’s intent, patterns, and autofix behavior.


## When to use autofix

This rule includes an autofix that will automatically add the `pr-` prefix to unnamespaced spacing utility classes. The autofix is safe to use as it only modifies the class names that match the spacing utility patterns.
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

This section states the autofix is “safe to use”, but the current fixer implementation operates via substring replacement on the raw node text, which can rewrite non-spacing class names that contain m-*/p-* substrings, and may not fix multiple different spacing classes in one pass due to overlapping fixes. After adjusting the fixer to be boundary-aware and non-overlapping, update this wording (or qualify it) so the docs match the actual behavior.

Suggested change
This rule includes an autofix that will automatically add the `pr-` prefix to unnamespaced spacing utility classes. The autofix is safe to use as it only modifies the class names that match the spacing utility patterns.
This rule includes an autofix that will automatically add the `pr-` prefix to unnamespaced spacing utility classes. The autofix operates on individual class tokens and is designed to only modify class names that match the spacing utility patterns, but you should still review the changes before committing.

Copilot uses AI. Check for mistakes.
Comment on lines +55 to +62
fix(fixer) {
// Get the raw text of the value node
const rawText = sourceCode.getText(valueNode)

// Replace the unnamespaced class with the namespaced version
// Using replaceAll to handle multiple occurrences of the same class
const fixedText = rawText.replaceAll(original, replacement)
return fixer.replaceText(valueNode, fixedText)
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

Autofix currently does a plain rawText.replaceAll(original, replacement) on the entire Literal/TemplateElement text. This can incorrectly rewrite other class names that merely contain the substring (e.g. fixing m-4 would also change my-m-4), and it also makes every report replace the whole node so fixes overlap and ESLint will apply at most one of them. Consider generating a single fixed string using a boundary-aware regex (or tokenizing on whitespace) and returning the same full-node fix for every report (or reporting once per node) so --fix reliably namespaces all matching classes without touching unrelated substrings.

Copilot uses AI. Check for mistakes.
// p-{size}, px-{size}, py-{size}, pt-{size}, pr-{size}, pb-{size}, pl-{size}
// Sizes: 0-12, auto, n1-n12 (negative)
// Responsive variants: mx-sm-2, mx-md-4, etc. (breakpoint embedded in class name)
const spacingUtilPattern = /(?<!\S)([mp][xytblr]?-(?:sm-|md-|lg-|xl-)?(?:auto|n?[0-9]+))(?!\S)/g
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

spacingUtilPattern currently matches any numeric size (n?[0-9]+), but the rule/docs comment say the supported scale is 0-12 and n1-n12. As-is, this will flag/auto-fix non-Primer classes like m-99. Tighten the regex to the intended range (including negative) to avoid false positives.

Suggested change
const spacingUtilPattern = /(?<!\S)([mp][xytblr]?-(?:sm-|md-|lg-|xl-)?(?:auto|n?[0-9]+))(?!\S)/g
const spacingUtilPattern = /(?<!\S)([mp][xytblr]?-(?:sm-|md-|lg-|xl-)?(?:auto|[0-9]|1[0-2]|n(?:[1-9]|1[0-2])))(?!\S)/g

Copilot uses AI. Check for mistakes.
Comment on lines +172 to +180
// Multiple unnamespaced classes - each is reported and fixed (first pass fixes first match only in test)
{
code: '<div className="m-4 p-2" />',
output: '<div className="pr-m-4 p-2" />',
errors: [
{messageId: 'namespaceRequired', data: {className: 'm-4', replacement: 'pr-m-4'}},
{messageId: 'namespaceRequired', data: {className: 'p-2', replacement: 'pr-p-2'}},
],
},
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

This test case’s output only applies the first fix (m-4), even though the rule reports (and should be able to fix) both m-4 and p-2 in a single --fix run. Once the rule’s fixer is made non-overlapping (e.g. produce a single full replacement per node), update the expected output to include both prefixes, and consider adding a regression test that ensures fixing m-4 does not rewrite my-m-4 or other non-token substrings.

Copilot uses AI. Check for mistakes.
'enforce-button-for-link-with-no-href': require('./rules/enforce-button-for-link-with-no-href'),
'enforce-css-module-default-import': require('./rules/enforce-css-module-default-import'),
'enforce-css-module-identifier-casing': require('./rules/enforce-css-module-identifier-casing'),
'namespace-spacing-utils': require('./rules/namespace-spacing-utils'),
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

CI enforces the presence of a Changeset file (see .github/workflows/check-for-changeset.yml). Since this PR adds a new user-facing rule, it likely needs a changeset in .changeset/*.md (or the PR must be labeled skip changeset) so the workflow doesn’t fail.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +3
# Enforce namespacing of spacing utility classes (namespace-spacing-utils)

Primer CSS spacing utility classes (margin and padding) should be namespaced with the `pr-` prefix to avoid conflicts with other CSS frameworks and ensure consistent styling.
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

The rule is documented here, but it isn’t currently listed in the top-level README.md “Rules” section (which enumerates all existing rules). Add namespace-spacing-utils to that list so users can discover the new rule and its docs.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants