Skip to content

Conversation

@YusukeHirao
Copy link
Member

@YusukeHirao YusukeHirao commented Jan 5, 2026

Issue #614 に対応し、コンポーネントルートで特定のプロパティを禁止する新しいStylelintルール component-root-disallowed-properties を追加。

変更内容

  • コンポーネントルート(ファイル名と一致するクラス名)で禁止プロパティをチェック
  • 疑似クラス(:hoverなど)内の禁止プロパティもチェック対象
  • 疑似要素(::beforeなど)内はチェック対象外
  • position: absolute, fixed, sticky を禁止対象に追加
  • 禁止プロパティを string | { [propName: string]: string } 形式で管理

禁止プロパティ

  • width, inline-size, height, block-size
  • margin関連(margin, margin-top, margin-right, margin-bottom, margin-left, margin-block, margin-inline, margin-block-start, margin-block-end, margin-inline-start, margin-inline-end)
  • inset関連(inset, inset-block, inset-inline, top, right, bottom, left)
  • position: absolute, fixed, sticky
  • justify-self, align-self, place-self
  • flex関連(flex, flex-grow, flex-shrink, flex-basis)
  • grid-area, float, clear

Note

Introduces a new Stylelint rule component-root-disallowed-properties and integrates it into src/index.ts.

  • Disallows root-level use of width/inline-size, height/block-size, all margin*, inset*/top/right/bottom/left, flex*, justify-self/align-self/place-self, grid-area, float, clear, and position: absolute|fixed|sticky; allows min/max-* variants
  • Targets only component root selectors whose class matches the file basename; checks inside pseudo-classes, ignores pseudo-elements and non-root/child selectors
  • Adds comprehensive tests in index.spec.ts and documentation in README.md with usage examples

Written by Cursor Bugbot for commit 3f7c782. Configure here.

Issue #614 に対応し、コンポーネントルートで特定のプロパティを禁止する
新しいStylelintルール component-root-disallowed-properties を追加。

- コンポーネントルート(ファイル名と一致するクラス名)で禁止プロパティをチェック
- 疑似クラス(:hoverなど)内の禁止プロパティもチェック対象
- 疑似要素(::beforeなど)内はチェック対象外
- min-* / max-* プレフィックスを許可(width, inline-size, height, block-size)
- 禁止プロパティ: width, height, margin関連, inset関連, position: absolute,
  justify-self, align-self, place-self, flex関連, grid-area, float, clear
- 禁止プロパティを string | { [propName: string]: string } 形式で管理
- position: fixed と position: sticky を禁止対象に追加
- プロパティと値の組み合わせを定数で一元管理できるように改善
禁止プロパティリストが網羅的であるため、min-*/max-*を特別に許可する
ロジックは不要。isAllowedMinMaxPropertyとshouldReportProperty関数を
削除し、isDisallowedPropertyを直接使用するように簡素化。
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

This PR is being reviewed by Cursor Bugbot

Details

Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.


// コンポーネントルート内の直接の子ノード(宣言)と疑似クラスを含むネストされたルールをチェック
checkDeclarations(rule);
}
Copy link

Choose a reason for hiding this comment

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

Pseudo-element check missing for top-level CSS rules

The main loop that processes top-level rules checks isComponentRoot but doesn't check hasPseudoElement before calling checkDeclarations. For nested rules, there's a hasPseudoElement check (line 208) that correctly skips pseudo-element selectors. However, flat CSS selectors like .button::before would pass isComponentRoot (since they contain the .button class) and have their declarations incorrectly flagged. According to the requirements, pseudo-element selectors should be excluded from checking regardless of whether they're nested or top-level.

Fix in Cursor Fix in Web

const [ruleFirstSelector] = ruleSelectors;
if (!ruleFirstSelector) {
return false;
}
Copy link

Choose a reason for hiding this comment

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

Multi-selector rules only check first selector for matching

The isComponentRoot function uses destructuring to extract only the first selector from ruleSelectors. For multi-selector rules like .button, .card { width: 100px; } in a file named card.css, the function only checks .button (first selector) and returns false, even though .card matches the component root basename. This would cause the disallowed property to go unreported when the component root class appears in a later position within a selector list.

Fix in Cursor Fix in Web

checkDeclarations(node);
}
}
}
Copy link

Choose a reason for hiding this comment

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

AtRule nodes inside component root not checked

The checkDeclarations function handles decl and rule node types but ignores atrule nodes like @media, @supports, or @container. In SCSS, at-rules can be nested inside component roots, and any declarations within them (e.g., width inside @media) would not be checked for forbidden properties. This allows violations to go unreported when forbidden properties are used inside nested media queries or other at-rules.

Fix in Cursor Fix in Web

@YusukeHirao YusukeHirao merged commit 4f19be7 into dev Jan 5, 2026
3 checks passed
@YusukeHirao YusukeHirao deleted the feat/#614 branch January 5, 2026 07:38
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