Skip to content

refactor(core): replace non-specific CSS selectors with explicit classes - #3460

Open
orrgottlieb wants to merge 1 commit into
masterfrom
fix/tighten-css-selectors
Open

orrgottlieb wants to merge 1 commit into
masterfrom
fix/tighten-css-selectors

Conversation

@orrgottlieb

Copy link
Copy Markdown
Contributor

What

Follow-up to the Toggle focus-selector cleanup. Replaces two low-specificity selector patterns (found in a repo-wide audit) with explicit class targets. Behavior-preserving.

Changes

Slider.disabled * { pointer-events: none } (universal descendant) → a .railDisabled marker class applied to SliderRail. Since pointer-events is inherited, disabling the rail disables its whole subtree, while the .disabled root keeps cursor: not-allowed. Same visual/interaction behavior.

MultiSelectedValues — bare div combinator targets replaced with existing classes:

  • > div:first-child> .chipWrapperWithOverflow:first-child
  • > div:not(.hiddenChip)> .chipWrapperWithOverflow:not(.hiddenChip), > .inputAndCounterWrapper (exactly the set the old selector matched: visible chips + the input/counter wrapper)

Deliberately left unchanged

  • TextField .textField * { box-sizing: border-box } — an idiomatic scoped reset; box-sizing isn't inherited so it can't move to the parent, and enumerating descendants would be more fragile.
  • The deeply-nested div { max-width: 100% } in MultiSelectedValues single-chip — targets the external Chips package's internals (no exposed class); out of scope.

Testing

  • ✅ stylelint clean
  • ✅ Slider + MultiSelectedValues/Dropdown tests pass (snapshots regenerated for the intended class changes)

🤖 Generated with Claude Code

Tighten two low-specificity selector patterns found in an audit:

- Slider: replace `.disabled * { pointer-events: none }` (universal
  descendant) with a `.railDisabled` marker class on SliderRail. The
  rail's subtree is disabled via inherited pointer-events while the root
  keeps its `not-allowed` cursor. No behavior change.
- MultiSelectedValues: replace bare `> div:first-child` and
  `> div:not(.hiddenChip)` with the existing `.chipWrapperWithOverflow`
  and `.inputAndCounterWrapper` classes. Behavior-equivalent.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@orrgottlieb
orrgottlieb requested a review from a team as a code owner August 3, 2026 13:20
@qodo-free-for-open-source-projects

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Refactor core CSS selectors to target explicit classes in Slider and Dropdown

✨ Enhancement 🕐 10-20 Minutes

Grey Divider

AI Description

• Replace broad Slider disabled descendant selector with an explicit rail marker class.
• Tighten MultiSelectedValues child selectors to target existing wrapper classes only.
• Preserve behavior while reducing selector ambiguity and unintended style bleed.
Diagram

graph TD
  SB["SliderBase"] --> SR["SliderRail"] --> SRS[["SliderRail styles"]]
  SB --> SBS[["SliderBase styles"]]
  MSV["MultiSelectedValues"] --> MSVS[["MultiSelectedValues styles"]]
Loading
High-Level Assessment

This approach is appropriate: replacing universal/bare-element selectors with explicit class targets reduces unintended styling side effects while preserving behavior. Alternatives like attribute-based selectors (e.g., [aria-disabled]) would require broader markup changes without clear benefit here.

Files changed (3) +15 / -6

Refactor (3) +15 / -6
MultiSelectedValues.module.scssNarrow MultiSelectedValues child selectors to explicit wrapper classes +3/-2

Narrow MultiSelectedValues child selectors to explicit wrapper classes

• Replaces direct-child 'div' combinator selectors with '.chipWrapperWithOverflow' and '.inputAndCounterWrapper' to precisely target the intended elements. Keeps the single-chip nested 'div' rule intact for external Chips internals.

packages/core/src/components/Dropdown/components/MultiSelectedValues/MultiSelectedValues.module.scss

SliderBase.module.scssIntroduce railDisabled class to avoid universal descendant selector for disabled state +6/-3

Introduce railDisabled class to avoid universal descendant selector for disabled state

• Removes '.disabled * { pointer-events: none; }' and introduces '.railDisabled { pointer-events: none; }' with a clarifying comment. Retains root disabled cursor/opacity styling.

packages/core/src/components/Slider/SliderBase/SliderBase.module.scss

SliderBase.tsxApply railDisabled marker class to SliderRail when disabled +6/-1

Apply railDisabled marker class to SliderRail when disabled

• Adds conditional 'className' on 'SliderRail' to apply the new '.railDisabled' style when the slider is disabled. Keeps root '.disabled' styling so the not-allowed cursor still displays.

packages/core/src/components/Slider/SliderBase/SliderBase.tsx

@qodo-free-for-open-source-projects

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

📦 Bundle Size Analysis

✅ No bundle size changes detected.

Unchanged Components
Component Base PR Diff
@vibe/button 14.83KB 14.8KB -29B 🟢
@vibe/clickable 3.56KB 3.54KB -17B 🟢
@vibe/dialog 17.54KB 17.53KB -8B 🟢
@vibe/icon-button 31.49KB 31.5KB +10B 🔺
@vibe/icon 10.42KB 10.4KB -22B 🟢
@vibe/layer 412B 412B 0B ➖
@vibe/layout 7.43KB 7.41KB -23B 🟢
@vibe/loader 3.25KB 3.22KB -33B 🟢
@vibe/tooltip 26.65KB 26.63KB -21B 🟢
@vibe/typography 28.82KB 28.81KB -16B 🟢
Accordion 3.97KB 3.95KB -21B 🟢
AccordionItem 31.81KB 31.83KB +22B 🔺
AlertBanner 36.27KB 36.27KB -3B 🟢
AlertBannerButton 16.4KB 16.34KB -59B 🟢
AlertBannerLink 12.84KB 12.76KB -85B 🟢
AlertBannerText 29.39KB 29.34KB -47B 🟢
AttentionBox 39.7KB 39.68KB -16B 🟢
Avatar 32.14KB 32.11KB -36B 🟢
AvatarGroup 58.25KB 58.23KB -18B 🟢
Badge 8.52KB 8.5KB -30B 🟢
BreadcrumbItem 30.09KB 30.04KB -51B 🟢
BreadcrumbMenu 33.59KB 33.6KB +12B 🔺
BreadcrumbMenuItem 42.53KB 42.41KB -128B 🟢
BreadcrumbsBar 3.3KB 3.3KB +4B 🔺
ButtonGroup 33.83KB 33.79KB -43B 🟢
Checkbox 32.24KB 32.28KB +36B 🔺
Chips 40.52KB 40.53KB +6B 🔺
ColorPicker 39.89KB 39.94KB +54B 🔺
ColorPickerContent 39.17KB 39.18KB +7B 🔺
Combobox 49.44KB 49.44KB -3B 🟢
Counter 7.58KB 7.55KB -36B 🟢
DatePicker 79.14KB 79.04KB -104B 🟢
Divider 3.04KB 3.02KB -20B 🟢
Dropdown 62.06KB 61.96KB -93B 🟢
EditableHeading 31.98KB 31.96KB -21B 🟢
EditableText 31.87KB 31.9KB +29B 🔺
EmptyState 35.9KB 35.87KB -34B 🟢
ExpandCollapse 31.62KB 31.58KB -40B 🟢
FormattedNumber 3.4KB 3.42KB +13B 🔺
GridKeyboardNavigationContext 2.2KB 2.19KB -4B 🟢
HiddenText 3.01KB 3KB -13B 🟢
Info 37.5KB 37.42KB -79B 🟢
Label 34.04KB 34.03KB -12B 🟢
Link 12.43KB 12.39KB -39B 🟢
List 38.35KB 38.31KB -44B 🟢
ListItem 30.92KB 30.91KB -8B 🟢
ListItemAvatar 32.3KB 32.33KB +28B 🔺
ListItemIcon 11.54KB 11.49KB -53B 🟢
ListTitle 30.44KB 30.42KB -14B 🟢
Menu 6.33KB 6.28KB -49B 🟢
MenuDivider 3.17KB 3.14KB -27B 🟢
MenuGridItem 4.75KB 4.72KB -29B 🟢
MenuItem 42.37KB 42.29KB -79B 🟢
MenuItemButton 35.51KB 35.41KB -108B 🟢
MenuTitle 30.83KB 30.73KB -98B 🟢
MenuButton 31.16KB 31.09KB -76B 🟢
Modal 44.58KB 44.54KB -45B 🟢
ModalContent 2.15KB 2.15KB 0B ➖
ModalHeader 31.23KB 31.18KB -50B 🟢
ModalMedia 5.14KB 5.12KB -19B 🟢
ModalFooter 33.01KB 33.04KB +30B 🔺
ModalFooterWizard 33.99KB 33.96KB -34B 🟢
ModalBasicLayout 6.6KB 6.55KB -53B 🟢
ModalMediaLayout 5.74KB 5.74KB -2B 🟢
ModalSideBySideLayout 3.94KB 3.91KB -28B 🟢
MultiStepIndicator 18.31KB 18.26KB -49B 🟢
NumberField 38.19KB 38.28KB +95B 🔺
ProgressBar 4.99KB 4.97KB -15B 🟢
RadioButton 31.28KB 31.29KB +14B 🔺
Search 36.04KB 36KB -46B 🟢
Skeleton 3.62KB 3.57KB -48B 🟢
Slider 39.29KB 39.33KB +38B 🔺
SplitButton 31.92KB 31.89KB -26B 🟢
SplitButtonMenu 6.43KB 6.44KB +8B 🔺
Steps 36.78KB 36.75KB -33B 🟢
Table 4.92KB 4.89KB -32B 🟢
TableBody 32.18KB 32.13KB -54B 🟢
TableCell 30.61KB 30.62KB +2B 🔺
TableContainer 2.89KB 2.88KB -6B 🟢
TableHeader 3.25KB 3.24KB -11B 🟢
TableHeaderCell 37.55KB 37.59KB +46B 🔺
TableRow 3.16KB 3.13KB -37B 🟢
TableRowMenu 33.85KB 33.82KB -36B 🟢
TableVirtualizedBody 36.81KB 36.79KB -19B 🟢
Tab 29.44KB 29.46KB +21B 🔺
TabList 6.6KB 6.55KB -45B 🟢
TabPanel 2.89KB 2.87KB -21B 🟢
TabPanels 3.47KB 3.44KB -27B 🟢
TabsContext 3KB 2.99KB -14B 🟢
TextArea 31.78KB 31.72KB -60B 🟢
TextField 34.83KB 34.77KB -56B 🟢
TextWithHighlight 29.79KB 29.72KB -78B 🟢
ThemeProvider 2.05KB 2.03KB -17B 🟢
Tipseen 36.54KB 36.47KB -69B 🟢
TipseenContent 37.05KB 36.99KB -63B 🟢
TipseenMedia 36.74KB 36.68KB -56B 🟢
TipseenWizard 39.28KB 39.09KB -188B 🟢
Toast 39.46KB 39.38KB -87B 🟢
ToastButton 16.16KB 16.14KB -19B 🟢
ToastLink 12.64KB 12.61KB -32B 🟢
Toggle 32.06KB 32.12KB +60B 🔺
TransitionView 3.01KB 3.01KB -8B 🟢
VirtualizedGrid 10.28KB 10.24KB -44B 🟢
VirtualizedList 9.95KB 9.93KB -18B 🟢
List (Next) 5.88KB 5.86KB -17B 🟢
ListItem (Next) 35.27KB 35.24KB -33B 🟢
ListTitle (Next) 30.75KB 30.7KB -56B 🟢

📊 Summary:

  • Total Base Size: 2.46MB
  • Total PR Size: 2.46MB
  • Total Difference: 2.84KB

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.

1 participant