Skip to content

breaking: remove onClick and clickable from CustomSvgIcon#3264

Open
rivka-ungar wants to merge 5 commits intovibe4from
breaking-change/customsvgicon-remove-onclick-clickable
Open

breaking: remove onClick and clickable from CustomSvgIcon#3264
rivka-ungar wants to merge 5 commits intovibe4from
breaking-change/customsvgicon-remove-onclick-clickable

Conversation

@rivka-ungar
Copy link
Contributor

@rivka-ungar rivka-ungar commented Feb 25, 2026

User description

Summary

  • Remove onClick and clickable props from CustomSvgIcon
  • Update Icon.tsx to not pass onClick to CustomSvgIcon
  • Update AvatarBadge.tsx to remove clickable from CustomSvgIcon usage
  • Add v3-to-v4 codemod (CustomSvgIcon-component-migration) with 5 tests
  • Update VIBE4_MIGRATION_GUIDE.md and VIBE4_CHANGELOG.md

Breaking Changes

  • CustomSvgIcon.onClick removed
  • CustomSvgIcon.clickable removed
  • Reason: SVG icons should be decorative; clickable patterns should use accessible wrappers (e.g. <button>)

Migration

// Before (v3)
<CustomSvgIcon src="/icon.svg" onClick={handleClick} clickable />

// After (v4)
<button onClick={handleClick}>
  <CustomSvgIcon src="/icon.svg" />
</button>

The codemod removes the props automatically; you'll need to add the button wrapper manually.

Task Link

Monday.com Task

Test Plan

  • 5 codemod tests pass
  • Icon package tests pass (11 tests)
  • Lint passes (0 errors)

🤖 Generated with Claude Code


PR Type

Bug fix, Enhancement


Description

  • Remove onClick and clickable props from CustomSvgIcon component

  • Update Icon.tsx and AvatarBadge.tsx to remove prop usage

  • Change blurOnMouseUp default from true to false in Button and ButtonGroup

  • Update migration guide and changelog with manual migration instructions

  • Fix tabIndex type from string to number in ColorPickerItemComponent


Diagram Walkthrough

flowchart LR
  A["CustomSvgIcon Props"] -->|Remove onClick| B["Decorative Icons Only"]
  A -->|Remove clickable| B
  C["Icon.tsx"] -->|Stop passing onClick| B
  D["AvatarBadge.tsx"] -->|Remove clickable prop| B
  E["Button/ButtonGroup"] -->|blurOnMouseUp: true to false| F["Updated Defaults"]
  G["Migration Guide"] -->|Manual wrapper pattern| H["Documentation"]
Loading

File Walkthrough

Relevant files
Breaking change
CustomSvgIcon.tsx
Remove onClick and clickable props                                             

packages/components/icon/src/Icon/CustomSvgIcon/CustomSvgIcon.tsx

  • Removed onClick callback prop from interface and implementation
  • Removed clickable boolean prop from interface and implementation
  • Updated useIconScreenReaderAccessProps call to always pass
    isClickable: false
  • Removed onClick attribute from SVG component rendering
+1/-12   
Bug fix
Icon.tsx
Stop passing onClick to CustomSvgIcon                                       

packages/components/icon/src/Icon/Icon.tsx

  • Removed onClick={onClickCallback} from CustomSvgIcon component usage
  • Icon component no longer passes click handler to CustomSvgIcon
+0/-1     
AvatarBadge.tsx
Remove clickable prop from CustomSvgIcon                                 

packages/core/src/components/Avatar/AvatarBadge.tsx

  • Removed clickable={tabIndex === -1} prop from CustomSvgIcon usage
  • Simplified CustomSvgIcon instantiation
+1/-1     
ColorPickerItemComponent.tsx
Fix tabIndex type from string to number                                   

packages/core/src/components/ColorPicker/components/ColorPickerItemComponent/ColorPickerItemComponent.tsx

  • Changed tabIndex from string "-1" to numeric -1
  • Fixes type consistency for tabIndex attribute
+1/-1     
Enhancement
Button.tsx
Change blurOnMouseUp default to false                                       

packages/components/button/src/Button/Button.tsx

  • Changed blurOnMouseUp default value from true to false
  • Affects button blur behavior on mouse up events
+1/-1     
ButtonGroup.tsx
Change blurOnMouseUp default to false                                       

packages/core/src/components/ButtonGroup/ButtonGroup.tsx

  • Changed blurOnMouseUp default value from true to false
  • Aligns with Button component default behavior
+1/-1     
Documentation
VIBE4_MIGRATION_GUIDE.md
Add CustomSvgIcon migration documentation                               

VIBE4_MIGRATION_GUIDE.md

  • Added CustomSvgIcon migration section documenting removed props
  • Provided before/after code examples for migration pattern
  • Documented manual migration requirement with button wrapper
  • Clarified no codemod available for this change
+15/-0   
VIBE4_CHANGELOG.md
Document CustomSvgIcon breaking change                                     

VIBE4_CHANGELOG.md

  • Added CustomSvgIcon section documenting breaking change
  • Explained reason for removal and migration approach
  • Marked codemod as unavailable (manual migration required)
+7/-0     

SVG icons should be purely decorative. The onClick and clickable props
are removed — wrap CustomSvgIcon in a button element for clickable patterns.

Changes:
- CustomSvgIcon.tsx: remove onClick and clickable from props and implementation
- Icon.tsx: remove onClick={onClickCallback} passed to CustomSvgIcon
- AvatarBadge.tsx: remove clickable={tabIndex === -1} from CustomSvgIcon usage
- Add v3-to-v4 codemod (CustomSvgIcon-component-migration) with 5 tests
- Update VIBE4_MIGRATION_GUIDE.md and VIBE4_CHANGELOG.md

BREAKING CHANGE: CustomSvgIcon.onClick and CustomSvgIcon.clickable removed.
Use a button wrapper for clickable SVG icon patterns.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@rivka-ungar rivka-ungar requested a review from a team as a code owner February 25, 2026 22:56
@qodo-free-for-open-source-projects
Copy link
Contributor

qodo-free-for-open-source-projects bot commented Feb 25, 2026

PR Reviewer Guide 🔍

(Review updated until commit cedcdcf)

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Title Format

⚠️ Title violates Conventional Commits. breaking: is not a valid Conventional Commits type; if this is a breaking change, it should be expressed via ! (e.g., feat!: / fix!:) and/or a BREAKING CHANGE footer.

#### CustomSvgIcon

- [x] **Status**: Done
- **Change**: Removed `onClick` and `clickable` props from `CustomSvgIcon`
- **Reason**: SVG icons should be decorative; use an accessible wrapper for clickable patterns
- **Migration**: Replace `<CustomSvgIcon onClick={fn} />` with `<button onClick={fn}><CustomSvgIcon /></button>`
- **Codemod**: ❌ Manual — wrap with a clickable element and move onClick to the wrapper
Behavior Change

Defaulting blurOnMouseUp to false changes focus/blur behavior for all button consumers who relied on the previous default. Confirm this is intended, update any related docs/migration notes, and ensure tests/behavior around focus management and accessibility still match expectations.

blurOnMouseUp = false,
"data-testid": dataTestId,
insetFocus = false,
tabIndex
A11y Semantics

useIconScreenReaderAccessProps is now always called with isClickable: false. Verify this doesn’t regress keyboard/screen-reader behavior for cases where the icon is used inside interactive wrappers (e.g., ensure the icon remains decorative and doesn’t accidentally get focus/role/label that conflicts with the wrapper).

const screenReaderAccessProps = useIconScreenReaderAccessProps({
  isClickable: false,
  label: ariaLabel,
  isDecorationOnly: ariaHidden
});

rivka-ungar and others added 4 commits February 26, 2026 13:19
After removing onClick/clickable from CustomSvgIcon, the hook call
was missing the required isClickable parameter causing a build error.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The codemod removed onClick/clickable props without adding a
clickable wrapper, which would silently break clickable icon UIs.
Users should manually wrap with a clickable element instead.

- Remove CustomSvgIcon-component-migration codemod and tests
- Update migration guide: no codemod, manual wrapper needed
- Update changelog: mark as manual migration

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Contributor

📦 Bundle Size Analysis

✅ No bundle size changes detected.

Unchanged Components
Component Base PR Diff
@vibe/button 17.74KB 17.71KB -31B 🟢
@vibe/clickable 6.07KB 6.05KB -21B 🟢
@vibe/dialog 53.85KB 53.8KB -48B 🟢
@vibe/icon-button 68.09KB 67.98KB -113B 🟢
@vibe/icon 13.01KB 12.99KB -18B 🟢
@vibe/layer 2.96KB 2.96KB 0B ➖
@vibe/layout 10.56KB 10.54KB -26B 🟢
@vibe/loader 5.8KB 5.82KB +16B 🔺
@vibe/tooltip 62.98KB 62.97KB -15B 🟢
@vibe/typography 65.4KB 65.39KB -15B 🟢
Accordion 6.35KB 6.34KB -16B 🟢
AccordionItem 68.13KB 68.14KB +3B 🔺
AlertBanner 72.93KB 72.86KB -76B 🟢
AlertBannerButton 19.23KB 19.19KB -38B 🟢
AlertBannerLink 15.56KB 15.52KB -38B 🟢
AlertBannerText 65.53KB 65.41KB -120B 🟢
AttentionBox 74.53KB 74.44KB -87B 🟢
AttentionBoxLink 15.41KB 15.34KB -77B 🟢
Avatar 68.36KB 68.28KB -82B 🟢
AvatarGroup 96.04KB 96.05KB +6B 🔺
Badge 43.53KB 43.56KB +26B 🔺
BreadcrumbItem 66.26KB 66.21KB -49B 🟢
BreadcrumbMenu 70.3KB 70.34KB +33B 🔺
BreadcrumbMenuItem 79.45KB 79.39KB -60B 🟢
BreadcrumbsBar 5.81KB 5.78KB -31B 🟢
ButtonGroup 70.25KB 70.33KB +84B 🔺
Checkbox 68.43KB 68.38KB -51B 🟢
Chips 77.18KB 77.1KB -82B 🟢
ColorPicker 76.35KB 76.21KB -143B 🟢
ColorPickerContent 75.57KB 75.46KB -107B 🟢
Combobox 86.37KB 86.39KB +19B 🔺
Counter 42.49KB 42.42KB -72B 🟢
DatePicker 134.59KB 134.47KB -126B 🟢
Divider 5.56KB 5.58KB +22B 🔺
Dropdown 125.94KB 125.92KB -22B 🟢
menu 59.95KB 59.94KB -13B 🟢
option 93.15KB 93.07KB -84B 🟢
singleValue 93.09KB 93KB -83B 🟢
EditableHeading 68.35KB 68.35KB +6B 🔺
EditableText 68.26KB 68.13KB -126B 🟢
EmptyState 72.75KB 72.69KB -59B 🟢
ExpandCollapse 68KB 67.98KB -17B 🟢
FormattedNumber 5.91KB 5.94KB +33B 🔺
GridKeyboardNavigationContext 4.66KB 4.65KB -5B 🟢
HiddenText 5.45KB 5.45KB -4B 🟢
Info 74.34KB 74.34KB -1B 🟢
Label 70.43KB 70.36KB -75B 🟢
LegacyModal 76.89KB 76.76KB -133B 🟢
LegacyModalContent 66.82KB 66.82KB -1B 🟢
LegacyModalFooter 3.45KB 3.45KB 0B ➖
LegacyModalFooterButtons 20.68KB 20.62KB -61B 🟢
LegacyModalHeader 72.97KB 72.85KB -124B 🟢
Link 15.23KB 15.15KB -82B 🟢
List 74.99KB 74.9KB -93B 🟢
ListItem 67.34KB 67.33KB -12B 🟢
ListItemAvatar 68.57KB 68.52KB -50B 🟢
ListItemIcon 14.21KB 14.22KB +8B 🔺
ListTitle 66.75KB 66.78KB +26B 🔺
Menu 8.71KB 8.72KB +10B 🔺
MenuDivider 5.65KB 5.65KB +5B 🔺
MenuGridItem 7.24KB 7.21KB -30B 🟢
MenuItem 79.22KB 79.32KB +109B 🔺
MenuItemButton 72.2KB 72.23KB +33B 🔺
MenuTitle 67.21KB 67.15KB -63B 🟢
MenuButton 67.8KB 67.72KB -86B 🟢
Modal 111.93KB 111.82KB -116B 🟢
ModalContent 4.77KB 4.77KB +2B 🔺
ModalHeader 67.64KB 67.55KB -89B 🟢
ModalMedia 7.77KB 7.75KB -11B 🟢
ModalFooter 69.48KB 69.49KB +7B 🔺
ModalFooterWizard 70.48KB 70.39KB -87B 🟢
ModalBasicLayout 9.25KB 9.23KB -15B 🟢
ModalMediaLayout 8.32KB 8.31KB -19B 🟢
ModalSideBySideLayout 6.36KB 6.38KB +26B 🔺
MultiStepIndicator 53.31KB 53.29KB -16B 🟢
NumberField 74.87KB 74.85KB -17B 🟢
LinearProgressBar 7.49KB 7.48KB -6B 🟢
RadioButton 67.59KB 67.58KB -8B 🟢
Search 72.45KB 72.4KB -53B 🟢
Skeleton 6.18KB 6.22KB +41B 🔺
Slider 75.97KB 75.88KB -98B 🟢
SplitButton 68.83KB 68.82KB -8B 🟢
SplitButtonMenu 8.89KB 8.88KB -7B 🟢
Steps 73.52KB 73.54KB +24B 🔺
Table 7.33KB 7.32KB -10B 🟢
TableBody 68.67KB 68.65KB -15B 🟢
TableCell 66.9KB 66.94KB +41B 🔺
TableContainer 5.36KB 5.37KB +14B 🔺
TableHeader 5.69KB 5.71KB +17B 🔺
TableHeaderCell 74.24KB 74.16KB -90B 🟢
TableRow 5.63KB 5.63KB +3B 🔺
TableRowMenu 70.62KB 70.58KB -46B 🟢
TableVirtualizedBody 73.42KB 73.25KB -169B 🟢
Tab 65.54KB 65.57KB +27B 🔺
TabList 8.97KB 8.94KB -28B 🟢
TabPanel 5.34KB 5.34KB -3B 🟢
TabPanels 5.97KB 5.96KB -12B 🟢
TabsContext 5.55KB 5.56KB +18B 🔺
TextArea 68.08KB 68.03KB -57B 🟢
TextField 71.36KB 71.37KB +5B 🔺
TextWithHighlight 65.86KB 65.84KB -20B 🟢
ThemeProvider 4.68KB 4.69KB +7B 🔺
Tipseen 73.16KB 73.21KB +47B 🔺
TipseenContent 73.65KB 73.72KB +76B 🔺
TipseenImage 73.49KB 73.48KB -9B 🟢
TipseenMedia 73.39KB 73.37KB -18B 🟢
TipseenWizard 76KB 75.96KB -42B 🟢
Toast 76.19KB 76.27KB +82B 🔺
ToastButton 19.07KB 19.02KB -52B 🟢
ToastLink 15.37KB 15.41KB +37B 🔺
Toggle 68.3KB 68.32KB +20B 🔺
TransitionView 37.69KB 37.73KB +41B 🔺
VirtualizedGrid 12.63KB 12.67KB +39B 🔺
VirtualizedList 12.42KB 12.4KB -14B 🟢
AttentionBox (Next) 76.41KB 76.5KB +87B 🔺
DatePicker (Next) 114.46KB 114.55KB +95B 🔺
Dialog (Next) 52.71KB 52.7KB -9B 🟢
Dropdown (Next) 97.57KB 97.32KB -256B 🟢
List (Next) 8.2KB 8.2KB +3B 🔺
ListItem (Next) 71.66KB 71.56KB -97B 🟢
ListTitle (Next) 67.08KB 67.04KB -43B 🟢

📊 Summary:

  • Total Base Size: 5.88MB
  • Total PR Size: 5.88MB
  • Total Difference: 3.04KB

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.

1 participant