Skip to content
Closed
Show file tree
Hide file tree
Changes from 68 commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
fd1c1c7
Add CLAUDE.md development guide
rivka-ungar Feb 25, 2026
853dd0d
feat: set up vibe4 migration infrastructure
rivka-ungar Feb 25, 2026
76e52d9
fix: resolve TypeScript build error in v3-to-v4 type-imports-migration
rivka-ungar Feb 25, 2026
3f46cbf
Merge branch 'master' into vibe4
rivka-ungar Feb 25, 2026
b69ab5a
chore: add vibe breaking change skill (#3258)
rivka-ungar Feb 25, 2026
57d9644
fix(Flex): remove stretch from justify prop (#3259)
rivka-ungar Feb 26, 2026
804190a
fix(Toggle): remove duplicate data-testid from Toggle internal elemen…
rivka-ungar Feb 26, 2026
dc031ba
chore: remove ThemeProvider alpha designation (#3277)
rivka-ungar Feb 26, 2026
ee9ba03
fix(Icon): props rename - remove "icon" prefix (#3256)
rivka-ungar Feb 26, 2026
1e37c32
fix(MenuItemIcon): remove deprecated label prop (#3262)
rivka-ungar Feb 26, 2026
76232a1
refactor: remove legacy DatePicker and moment.js dependency (#3278)
rivka-ungar Feb 26, 2026
bf9752a
fix(skill): use conventional commits for breaking change templates (#…
rivka-ungar Feb 26, 2026
b526203
refactor: remove old Dropdown (#3279)
rivka-ungar Feb 26, 2026
7040c08
refactor: remove legacy AttentionBox (#3281)
rivka-ungar Feb 26, 2026
58619c6
refactor: remove LegacyModal, promote new Modal to main export (#3282)
rivka-ungar Feb 26, 2026
1864120
feat: remove enums and static properties from Vibe components (#3283)
talkor Feb 27, 2026
413147e
feat(Chips): remove disableClickableBehavior prop
rivka-ungar Mar 1, 2026
253235d
fix: remove onClick and clickable from CustomSvgIcon (#3264)
rivka-ungar Mar 1, 2026
d425ea7
feat: make Steps finish button default on last step (#3275)
rivka-ungar Mar 1, 2026
6781ee5
fix(Clickable): remove string types from ariaHasPopup and tabIndex (#…
rivka-ungar Mar 1, 2026
0562c35
refactor: Rename LinearProgressBar to ProgressBar (#3272)
rivka-ungar Mar 1, 2026
bc98f26
fix(TextWithHighlight): remove tooltipPosition prop (#3274)
rivka-ungar Mar 1, 2026
52501bf
feat(MenuButton): default focusItemIndexOnMount to 0 for Menu childre…
rivka-ungar Mar 1, 2026
22f7f71
feat(Icon)!: default ariaHidden to true for decorative icons
rivka-ungar Mar 1, 2026
ec31b19
Revert "feat(Icon)!: default ariaHidden to true for decorative icons"
rivka-ungar Mar 1, 2026
f9364e8
feat(Dialog): replace legacy class-based Dialog with new floating-ui …
rivka-ungar Mar 2, 2026
9176948
feat(Tooltip): make TooltipProps extend DialogProps (#3292)
rivka-ungar Mar 2, 2026
30279bf
feat(Tipseen): remove TipseenImage in favor of TipseenMedia (#3293)
rivka-ungar Mar 2, 2026
cdcae41
chore(TableCellSkeleton): remove @supports fallback for aspect-ratio …
talkor Mar 2, 2026
dca47d6
feat(Link): remove @supports CSS block in favor of direct logical pro…
rivka-ungar Mar 2, 2026
fcb0bf0
feat(Dialog): change addKeyboardHideShowTriggersByDefault default to …
rivka-ungar Mar 2, 2026
ec10fb2
feat(Dialog): remove enableNestedDialogLayer, always use LayerProvide…
rivka-ungar Mar 2, 2026
5df39ae
feat(MenuItem): narrow children type to MenuChild only (not array) (#…
rivka-ungar Mar 3, 2026
deb39ea
chore: merge master into vibe4
rivka-ungar Mar 3, 2026
9158df3
chore: remove erroneously merged a11y-dialog and body-scroll-lock deps
rivka-ungar Mar 3, 2026
c3bdba8
fix: restore indentation in packages/core/package.json
rivka-ungar Mar 3, 2026
f4392c9
fix(ProgressBar): replace LinearProgressBar with ProgressBar in tests
rivka-ungar Mar 3, 2026
02d8431
fix(ProgressBar): replace LinearProgressBar with ProgressBar in docs …
rivka-ungar Mar 3, 2026
80dcdf3
feat(TextField): rename iconName prop to icon (#3270)
rivka-ungar Mar 3, 2026
872e7bf
feat: rename camelCase aria props to standard HTML aria-* attributes …
rivka-ungar Mar 3, 2026
92d182a
fix(VirtualizedGrid): correct itemRenderer return type to ReactElemen…
rivka-ungar Mar 3, 2026
f423be2
chore(MultiStepIndicator): update react-transition-group to use nodeR…
talkor Mar 3, 2026
0540786
feat(Toggle): remove noSpacing prop, auto-remove margin when labels a…
talkor Mar 3, 2026
9599a88
feat(useKeyEvent): change callback type from GenericEventCallback to …
rivka-ungar Mar 3, 2026
7e49637
feat(style): rename monday-ui-style package to @vibe/style (#3301)
talkor Mar 3, 2026
b7b3922
chore: replace CSS physical properties with logical properties (#3313)
talkor Mar 3, 2026
9ecc82f
chore(hooks): remove deprecated useMergeRefs hook (#3306)
talkor Mar 3, 2026
0f68dee
docs: add global box-sizing: border-box readme (#3315)
rivka-ungar Mar 3, 2026
e5695c0
feat(Icon): pass size prop to CustomSvgIcon for type="src" icons (#3314)
rivka-ungar Mar 3, 2026
10f2872
fix(TextField): replace iconsNames object prop with flat props (#3265)
rivka-ungar Mar 3, 2026
61d2da8
chore(types): remove VibeComponent type (#3305)
talkor Mar 3, 2026
05380b5
chore(useActiveDescendantListFocus): remove backwardCompatibilityCrea…
talkor Mar 3, 2026
e870562
feat(useListenFocusTriggers): remove from public API (#3304)
talkor Mar 4, 2026
d864c05
feat(VirtualizedList): remove deprecated getItemHeight and onVertical…
talkor Mar 5, 2026
10e8847
feat(style): use --placeholder-color token and reduce TextField paddi…
rivka-ungar Mar 5, 2026
1e1755b
chore: remove framer-motion, replace with react-transition-group + CS…
talkor Mar 5, 2026
8885f48
refactor(core): migrate JSX/JS files to TSX/TS, remove allowJs (#3318)
talkor Mar 5, 2026
b504327
feat(style): remove deprecated semantic spacing tokens (#3320)
rivka-ungar Mar 5, 2026
dbc964a
feat(codemod): add missing v3-to-v4 migration codemods (#3322)
rivka-ungar Mar 8, 2026
062758e
feat(mcp): add v4-migration analysis tool (#3323)
rivka-ungar Mar 8, 2026
5959d66
docs: Vibe 4 migration guide (#3321)
rivka-ungar Mar 8, 2026
012726e
Publish
rivka-ungar Mar 8, 2026
ac5a191
yarn lock
rivka-ungar Mar 8, 2026
f305f32
Publish
rivka-ungar Mar 8, 2026
f7ca751
docs: migration guide (#3324)
talkor Mar 9, 2026
fdc4dab
fix e2e
talkor Mar 10, 2026
5ce5987
chore: upgrade to TS 5 (#3325)
talkor Mar 11, 2026
71f526c
ci: add a v3 release workflow
talkor Mar 11, 2026
1ac7609
fix: add missing @vibe/style dependency to component packages (#3330)
rivka-ungar Mar 12, 2026
49187f2
feat(mcp): detect old vs new API usage for promoted components (#3326)
rivka-ungar Mar 12, 2026
3bc2c6b
fix: add missing @vibe/style dependency to @vibe/base (#3331)
rivka-ungar Mar 12, 2026
01832ac
Publish
rivka-ungar Mar 12, 2026
8c8df23
publish
rivka-ungar Mar 12, 2026
3e6ed76
chore: remove gitHead from package.json files
rivka-ungar Mar 12, 2026
36faa70
Merge branch 'master' into vibe4
rivka-ungar Mar 13, 2026
a457b8c
feat(dialog): default enableNestedDialogLayer to true (#3332)
rivka-ungar Mar 15, 2026
5ee54fe
add Menu
talkor Mar 15, 2026
b68de2f
fix(testkit): fix e2e locators broken by vibe4 changes (#3333)
rivka-ungar Mar 16, 2026
8074005
Merge branch 'vibe4' into v3-release-workflow
talkor Mar 16, 2026
5d04fb2
Merge branch 'master' into v3-release-workflow
talkor Mar 24, 2026
39c0646
lock
talkor Mar 24, 2026
39b4f99
Merge branch 'master' into v3-release-workflow
talkor Mar 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
598 changes: 598 additions & 0 deletions .claude/skills/vibe-breaking-change/SKILL.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
# Codemod Best Practices for Vibe Breaking Changes

## Lessons Learned from Real Implementation

This guide covers critical lessons learned from implementing the Icon component prop renames codemod, including major pitfalls to avoid.

## ❌ Common Mistakes to Avoid

### 1. Using Non-Existent Functions

**WRONG:**
```typescript
import { renameProp } from "../../../src/utils"; // ❌ Doesn't exist

elements.forEach(elementPath => {
if (isPropExists(j, elementPath, "oldProp")) {
renameProp(j, elementPath, "oldProp", "newProp"); // ❌ Function doesn't exist
}
});
```

**CORRECT:**
```typescript
import { migratePropsNames } from "../../../src/utils"; // ✅ Real function

elements.forEach(elementPath => {
migratePropsNames(j, elementPath, filePath, componentName, {
oldProp: "newProp",
anotherOld: "anotherNew"
}); // ✅ Handles all props in one efficient call
});
```

### 2. Wrong Import Path Detection

**WRONG:**
```typescript
// This only finds "monday-ui-react-core" imports, not "@vibe/core"
const imports = getCoreImportsForFile(root);
```

**CORRECT:**
```typescript
import { NEW_CORE_IMPORT_PATH } from "../../../src/consts";

// This finds "@vibe/core" imports correctly
const imports = getImports(root, NEW_CORE_IMPORT_PATH);
```

### 3. Inefficient Multiple Loops

**WRONG:**
```typescript
elements.forEach(elementPath => {
// Separate check for each prop - inefficient!
if (isPropExists(j, elementPath, "iconLabel")) {
renameProp(j, elementPath, "iconLabel", "label");
}
if (isPropExists(j, elementPath, "iconType")) {
renameProp(j, elementPath, "iconType", "type");
}
if (isPropExists(j, elementPath, "iconSize")) {
renameProp(j, elementPath, "iconSize", "size");
}
});
```

**CORRECT:**
```typescript
elements.forEach(elementPath => {
// Single call handles all prop renames efficiently
migratePropsNames(j, elementPath, filePath, componentName, {
iconLabel: "label",
iconType: "type",
iconSize: "size"
});
});
```

## 🔧 Proven Codemod Pattern

Based on successful v2-v3 codemods, use this proven pattern:

```typescript
import {
wrap,
getImports,
getComponentNameOrAliasFromImports,
findComponentElements,
migratePropsNames
} from "../../../src/utils";
import { NEW_CORE_IMPORT_PATH } from "../../../src/consts";
import { TransformationContext } from "../../../types";

function transform({ j, root, filePath }: TransformationContext) {
// 1. Find imports from correct package
const imports = getImports(root, NEW_CORE_IMPORT_PATH);

// 2. Check if component is imported
const componentName = getComponentNameOrAliasFromImports(j, imports, "ComponentName");
if (!componentName) return;

// 3. Find all component elements
const elements = findComponentElements(root, componentName);
if (!elements.length) return;

// 4. Migrate props efficiently
elements.forEach(elementPath => {
migratePropsNames(j, elementPath, filePath, componentName, {
oldProp1: "newProp1",
oldProp2: "newProp2",
oldProp3: "newProp3"
});
});
}

export default wrap(transform);
```

## ⚠️ JSCodeshift Formatting Artifacts

### The Problem

JSCodeshift can add unnecessary parentheses around JSX elements, even in files that **don't use the target component**.

**Example:**
```jsx
// Original code
<div className="wrapper">
<span>Content</span>
</div>

// After codemod (WRONG!)
(<div className="wrapper">
<span>Content</span>
</div>)
```

### Root Cause

JSCodeshift parses and rebuilds the AST, which can introduce formatting changes even when no transforms are applied.

### Prevention Strategies

#### 1. Target Specific Files
```bash
# WRONG - transforms entire directory
npx jscodeshift -t transform.js packages/core/src/components/

# BETTER - target specific files known to use the component
npx jscodeshift -t transform.js packages/core/src/components/Button/Button.tsx packages/core/src/components/IconButton/IconButton.tsx
```

#### 2. Use Dry Run First
```bash
# Always run dry first to see what changes
npx jscodeshift -t transform.js packages/ --dry

# Review the output carefully
# Only proceed if changes look correct
npx jscodeshift -t transform.js packages/
```

#### 3. Filter by Import Detection
```typescript
function transform({ j, root, filePath }: TransformationContext) {
// Only proceed if file actually imports the component
const imports = getImports(root, NEW_CORE_IMPORT_PATH);
const componentName = getComponentNameOrAliasFromImports(j, imports, "ComponentName");
if (!componentName) return; // ✅ Exit early, no changes

// ... rest of transform
}
```

### Cleanup Process

If formatting artifacts slip through:

```bash
# 1. Identify files with unintended changes
git diff HEAD~1 HEAD --name-only | grep -E "(Checkbox|AvatarGroup|Dropdown)"

# 2. Review each file
git diff HEAD~1 HEAD -- path/to/file.tsx

# 3. Manual cleanup
# Remove extra parentheses: (<div> → <div>
# Fix indentation as needed

# 4. Commit cleanup
git add .
git commit -m "fix: remove codemod formatting artifacts"
```

## 🧪 Testing Best Practices

### Test Development
```typescript
// Cover edge cases in tests
defineInlineTest(
transform,
{},
prependImport('const element = <Icon icon={Home} iconLabel="Home" iconType="svg" iconSize={24} />;'),
prependImport('const element = <Icon icon={Home} label="Home" type="svg" size={24} />;'),
"should rename all three props"
);

// Test aliased imports
defineInlineTest(
transform,
{},
`import { Icon as VibeIcon } from "@vibe/core";
const element = <VibeIcon icon={Home} iconLabel="Home" />;`,
`import { Icon as VibeIcon } from "@vibe/core";
const element = <VibeIcon icon={Home} label="Home" />;`,
"should work with aliased imports"
);
```

### Expected Results
- **7-8 out of 8 tests pass** - indicates working codemod
- **1 formatting test failure** - expected jscodeshift artifact (acceptable)
- **0 tests pass** - indicates broken codemod logic

## 📝 Documentation Integration

### Migration Guide Entry
```markdown
## ComponentName API Changes

### Breaking Changes
**Props Renamed:**
- `oldProp` → `newProp`
- `anotherOld` → `anotherNew`

### Automated Migration
```bash
npx @vibe/codemod component-name-props-update src/
```

### Manual Migration
[Include before/after examples]
```

### Changelog Entry
```markdown
#### ComponentName v2.0.0
- **BREAKING**: Renamed props for better consistency
- **Migration**: Use `npx @vibe/codemod component-name-props-update`
- **Task**: Monday.com #[task-id]
```

## 🚀 Success Criteria

A successful codemod implementation should:

1. **✅ Follow established patterns** from v2-v3 codemods
2. **✅ Use correct utility functions** (migratePropsNames, getImports)
3. **✅ Handle import paths correctly** (NEW_CORE_IMPORT_PATH)
4. **✅ Be efficient** (single loop, batch prop updates)
5. **✅ Have comprehensive tests** (7+ passing test cases)
6. **✅ Minimize formatting artifacts** (targeted file updates)
7. **✅ Include cleanup process** (for any artifacts that slip through)

## 🔄 Iteration Process

1. **RED**: Write failing tests first
2. **GREEN**: Implement minimal working codemod
3. **REFACTOR**: Fix issues, improve efficiency
4. **CLEANUP**: Remove formatting artifacts
5. **DOCUMENT**: Update migration guide and changelog
6. **VALIDATE**: Test on real codebase examples
Loading
Loading