-
-
Notifications
You must be signed in to change notification settings - Fork 336
[tabs] Fire onValueChange for automatic tab selection #3758
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
commit: |
Bundle size report
Check out the code infra dashboard for more information about this PR. |
✅ Deploy Preview for base-ui ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Greptile SummaryThis PR fixes issue #2097 by ensuring Key changes:
Issue found:
The test coverage is thorough and validates the main scenarios. The implementation properly uses Confidence Score: 4/5
Important Files Changed
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4 files reviewed, 1 comment
| let reason: TabsRoot.ChangeEventReason; | ||
| if (isInitialRun) { | ||
| reason = REASONS.initial; | ||
| } else if (selectionIsDisabled) { | ||
| reason = REASONS.disabled; | ||
| } else { | ||
| reason = REASONS.missing; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: The reason assignment logic always uses 'initial' for the first run, even when an explicit defaultValue is provided but the corresponding tab doesn't exist. According to the PR description, 'initial' should only be used when "no value/defaultValue provided", but this code will fire with 'initial' reason even if defaultValue={1} is provided but tab 1 is missing.
Consider refining the logic:
| let reason: TabsRoot.ChangeEventReason; | |
| if (isInitialRun) { | |
| reason = REASONS.initial; | |
| } else if (selectionIsDisabled) { | |
| reason = REASONS.disabled; | |
| } else { | |
| reason = REASONS.missing; | |
| } | |
| // Determine the appropriate reason based on context: | |
| // - 'initial': First automatic selection (no value/defaultValue provided) | |
| // - 'disabled': Tab became disabled after initial render | |
| // - 'missing': Tab was removed from DOM or never existed | |
| let reason: TabsRoot.ChangeEventReason; | |
| if (isInitialRun && isAutomaticDefault) { | |
| reason = REASONS.initial; | |
| } else if (selectionIsDisabled) { | |
| reason = REASONS.disabled; | |
| } else { | |
| reason = REASONS.missing; | |
| } |
This ensures 'initial' is only used when no explicit value was provided, making the behavior match the documentation.
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/react/src/tabs/root/TabsRoot.tsx
Line: 261:268
Comment:
**logic:** The reason assignment logic always uses `'initial'` for the first run, even when an explicit `defaultValue` is provided but the corresponding tab doesn't exist. According to the PR description, `'initial'` should only be used when "no value/defaultValue provided", but this code will fire with `'initial'` reason even if `defaultValue={1}` is provided but tab 1 is missing.
Consider refining the logic:
```suggestion
// Determine the appropriate reason based on context:
// - 'initial': First automatic selection (no value/defaultValue provided)
// - 'disabled': Tab became disabled after initial render
// - 'missing': Tab was removed from DOM or never existed
let reason: TabsRoot.ChangeEventReason;
if (isInitialRun && isAutomaticDefault) {
reason = REASONS.initial;
} else if (selectionIsDisabled) {
reason = REASONS.disabled;
} else {
reason = REASONS.missing;
}
```
This ensures `'initial'` is only used when no explicit value was provided, making the behavior match the documentation.
How can I resolve this? If you propose a fix, please make it concise.
Fixes a bug where the
onValueChangecallback was not invoked when the selected tab changed automatically due to external factors.Previously, onValueChange only fired for user-initiated tab changes (clicks, keyboard navigation). It did not fire when:
Now,
onValueChangefires in all these scenarios with appropriate reason values.It also fires during initial render when no
valueordefaultValueis provided, and the component automatically selects the first enabled tab.New reason values in onValueChange:
'initial': First automatic selection on mount (no value/defaultValue provided)'disabled': Selected tab became disabled after initial render'missing': Selected tab was removed from the DOMThe existing
'none'reason is used for user-initiated changes.Fixes #2097