microsoft / vscode-webview-ui-toolkit

A component library for building webview-based extensions in Visual Studio Code.
MIT License
1.97k stars 131 forks source link

On first interaction the last Radio item in a Radio group is always selected #476

Open IanMatthewHuff opened 1 year ago

IanMatthewHuff commented 1 year ago

Describe the bug

We're currently using the <VSCodeRadioGroup> and <VSCodeRadio> controls in a VS Code Webview. When you first try to click on any of the Radio Buttons the last button in the list will always be selected. After this first click / selection it will then work correctly from now on out.

To reproduce

We are using the React Components in a webview, but I can reproduce this with the radio-group-sample CodeSandbox provided by this repo.

  1. Open this website: https://codesandbox.io/s/radio-group-sample-5c8rq2?file=/index.html
  2. Attempt to click the first or second item in one of the radio groups
  3. To repro again, just reload the browser in the codesandbox

Expected behavior

The radio control that is clicked should be selected.

Current behavior

The last radio control in the group is selected.

Screenshots

RadioIssue

Also this is non-blocking and I'm far from an HTML guru (so I might be misunderstanding). But per the docs here: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/change_event

When a <input type="checkbox"> element is checked or unchecked (by clicking or using the keyboard); When a <input type="radio"> element is checked (but not when unchecked);

I hooked up to the onChange of <VSCodeRadio> and currently I see it firing for the radio button that is being deselected or switched away from, and from the radio button that is being switched to. Per the docs I would have expected it only for the item that is being switched to.

IanMatthewHuff commented 1 year ago

Also just to say this is the first extension that I've worked on since the UI toolkit has been available, and it's been a real boon so far. Great addition for helping make things more consistent.

degrammer commented 1 year ago

I'm having the same issue, in my case, it happens when rendering the vscode-radio-group, not just when clicking a vscode-radio, the last item is always checked.

hawkticehurst commented 1 year ago

Hi all, it looks like this is a bug with FAST Foundation (the technology we use to build the toolkit), so I've gone ahead and bubbled the issue up to them.

I'll keep this issue open to track the bug on the toolkit side of things and adopt the FAST change/fix once it lands :)

In the meantime let me know if you have any questions and I'll do my best to answer them!

hawkticehurst commented 1 year ago

Actually, a quick addendum/temporary solution!

Looking at the FAST code again I think I realized what's going wrong.

I believe the issue is caused when no explicit value attribute is set on the radio elements. When this happens a current-value attribute is automatically set with the exact same value for all radio elements. This subsequently causes a boolean check in FAST Foundation code to pass for all radio elements and eventually select the last radio element because (presumably) it is the last radio element to have the check run on it.

By explicitly adding value attributes with different values, the component works.

So to be clear, this works:

<vscode-radio-group>
  <label slot="label">Radio Group Label</label>
  <vscode-radio value="hi">Radio Label</vscode-radio>
  <vscode-radio value="hello">Radio Label</vscode-radio>
  <vscode-radio value="hey">Radio Label</vscode-radio>
</vscode-radio-group>

And this does not:

<vscode-radio-group>
  <label slot="label">Radio Group Label</label>
  <vscode-radio>Radio Label</vscode-radio>
  <vscode-radio>Radio Label</vscode-radio>
  <vscode-radio>Radio Label</vscode-radio>
</vscode-radio-group>
hawkticehurst commented 1 year ago

I'm still leaving the FAST issue open and asking them to better handle when value attributes are not explicitly set. But adding explicit value attributes should fix this problem in the meantime!

Please let me know if this works on your end and if there are any further issues you run into :)