-
-
Notifications
You must be signed in to change notification settings - Fork 173
fix: BFormRadioGroup - prevent forwarding option attrs that override input id #2899
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: main
Are you sure you want to change the base?
fix: BFormRadioGroup - prevent forwarding option attrs that override input id #2899
Conversation
…ide input id (fix label/click behavior) - Do not spread option objects into normalized options - Generate deterministic id per option (group id + index) - Add unit test reproducing 'Id' valueField case
|
|
WalkthroughThe changes refactor option normalization in BFormRadioGroup to explicitly include only id, value, disabled, and text fields instead of spreading all original option properties. Index-based id generation is added for uniqueness. A new test validates label-to-input linkage with custom field names. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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.
Actionable comments posted: 0
🧹 Nitpick comments (2)
packages/bootstrap-vue-next/src/components/BFormRadio/form-radio-group.spec.ts (1)
204-235: Good test coverage for the label-input linkage fix.The test correctly validates that label
formatches inputidand that clicking works with custom field names. This effectively reproduces and validates the fix for the reported bug.Consider verifying modelValue update:
The test checks that the input becomes checked but doesn't verify that
modelValueis updated. Consider adding an assertion after line 234:await inputs[0].trigger('click') expect((inputs[0].element as HTMLInputElement).checked).toBe(true) + // Verify modelValue is updated to the selected option's value + expect(wrapper.vm.modelValue).toBe(1)packages/bootstrap-vue-next/src/components/BFormRadio/BFormRadioGroup.vue (1)
84-91: Consider tightening the type definition for clarity.The type definition includes
[key: string]: unknownwhich suggests normalized options may contain additional arbitrary properties. However, the implementation (lines 101-116) now explicitly provides onlyid,value,disabled, andtextwithout spreading additional properties from the original option.While not incorrect (a more permissive type is valid), you could improve type precision by removing the index signature:
const normalizeOptions = computed< { + id: string text: string | undefined - // eslint-disable-next-line @typescript-eslint/no-explicit-any value: any disabled?: boolean | undefined - [key: string]: unknown }[] >(() =>This would make the type definition more accurately reflect the implementation and clarify that only these specific properties are included.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/bootstrap-vue-next/src/components/BFormRadio/BFormRadioGroup.vue(1 hunks)packages/bootstrap-vue-next/src/components/BFormRadio/form-radio-group.spec.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
packages/bootstrap-vue-next/src/components/**
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Create and modify Vue components only under packages/bootstrap-vue-next/src/components/
Files:
packages/bootstrap-vue-next/src/components/BFormRadio/form-radio-group.spec.tspackages/bootstrap-vue-next/src/components/BFormRadio/BFormRadioGroup.vue
**/*.spec.ts
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Write tests following existing patterns in *.spec.ts files
Files:
packages/bootstrap-vue-next/src/components/BFormRadio/form-radio-group.spec.ts
packages/bootstrap-vue-next/src/components/**/*.vue
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Keep component-specific styles within their respective .vue single-file components
Files:
packages/bootstrap-vue-next/src/components/BFormRadio/BFormRadioGroup.vue
🧠 Learnings (2)
📚 Learning: 2025-09-12T14:46:49.416Z
Learnt from: CR
Repo: bootstrap-vue-next/bootstrap-vue-next PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-12T14:46:49.416Z
Learning: Applies to packages/bootstrap-vue-next/src/App.vue : Use packages/bootstrap-vue-next/src/App.vue as a local test area for component changes
Applied to files:
packages/bootstrap-vue-next/src/components/BFormRadio/form-radio-group.spec.tspackages/bootstrap-vue-next/src/components/BFormRadio/BFormRadioGroup.vue
📚 Learning: 2025-04-28T22:48:46.738Z
Learnt from: xvaara
Repo: bootstrap-vue-next/bootstrap-vue-next PR: 2425
File: packages/bootstrap-vue-next/src/plugins/popoverController/index.ts:138-140
Timestamp: 2025-04-28T22:48:46.738Z
Learning: In bootstrap-vue-next, `PopoverOrchestratorParam` includes an `id` field of type `ControllerKey` through inheritance from base types. This field is declared in the `BvControllerOptions` interface and propagated through the type hierarchy.
Applied to files:
packages/bootstrap-vue-next/src/components/BFormRadio/BFormRadioGroup.vue
🔇 Additional comments (1)
packages/bootstrap-vue-next/src/components/BFormRadio/BFormRadioGroup.vue (1)
93-117: Excellent fix that correctly prevents attribute collision.The refactored implementation properly addresses the bug by building a clean normalized option object containing only the specific properties (
id,value,disabled,text) instead of spreading the original option. This prevents arbitrary keys likeIdfrom being forwarded as attributes to the native<input>element where they could override the computediddue to HTML's case-insensitive attribute handling.The index-based ID generation pattern (
${computedId.value}__${index}) provides deterministic IDs, and the fallback logic (el.id ?? ...) correctly respects explicitly provided IDs while ensuring every option gets an ID.The inline comment (lines 102-109) is particularly valuable as it documents the rationale for future maintainers.
|
Then, maybe we should prevent the forwarding of the attributes declared in textField / valueField ? I don't see a case where one would expect/need the properties contained in textField / valueField to be forwarded. Something like: |




Fixes #2898
Disclaimer: this fix was coded by Copilot using "Code with agent mode" button.
Summary
This PR fixes a bug where object option keys (for example
Id) were forwarded via $attrs onto the native and could override the computed id (HTML attribute names are case-insensitive). That broke the label for association and prevented clicks on labels/buttons from selecting the radio when using textField/valueField and buttons styles.What I changed:
Validation:
Files changed:
Please review and let me know if you prefer forcing generated ids even when id is provided by options.