vscode-webview-ui-toolkit icon indicating copy to clipboard operation
vscode-webview-ui-toolkit copied to clipboard

VSCodeDropdown in React with dynamically rendered children doesn't auto select provided value property

Open LuukVaal opened this issue 2 years ago • 7 comments

Describe the bug

When using VSCodeDropdown in React with a value property and dynamically rendered children where the children are rendered later than the value property is set, the dropdown selects the default option (which is the only option that is not dynamically rendered) and does not automatically selects the option corresponding to the value property.

To reproduce

const [options, setOptions] = useState([]);

/* at some point later, after fetching data for example */
setOptions(['option-1', 'option-2']);

/* in the render function */
<VSCodeDropdown
  value='option-1'
>
  <VSCodeOption key='default'>default</VSCodeOption>
  {options.map((option) => {
    return (<VSCodeOption key={option}>{option}</VSCodeOption>);
  })}
</VSCodeDropdown>

StackBlitz example: https://stackblitz.com/edit/react-ts-71etx8?file=App.tsx

Expected behavior

The dropdown automatically selects the dynamically rendered option based on the existing value property.

Current behavior

The dropdown will keep the default (first) option selected.

Note that conditionally rendering the dropdown list does solve this issue, however that should not be necessary.

Screenshots

See this StackBlitz demo: https://stackblitz.com/edit/react-ts-71etx8?file=App.tsx

Desktop (please complete the following information):

  • OS Version: Windows 11 (Build 22622)
  • Toolkit Version: 1.1.0 & 1.2.0
  • React version: 18.2.0

LuukVaal avatar Dec 12 '22 15:12 LuukVaal

Hey @LuukVaal!

Perhaps I'm misunderstanding your ask here, but the reason (or at least one of the big reasons) the above code isn't working is because native HTML <select> elements (and therefore the <vscode-dropdown>/<VSCodeDropdown> components because they are an implementation of select) do not have a value attribute.

To set a default value, you must add a selected attribute to the desired <option>/<vscode-option>/<VSCodeOption>.

<VSCodeDropdown>
  <VSCodeOption>option-1</VSCodeOption>
  <VSCodeOption selected>option-2</VSCodeOption> // <-- this will be the selected value
  <VSCodeOption>option-3</VSCodeOption>
</VSCodeDropdown>

Further reference: https://stackoverflow.com/questions/5589629/value-attribute-on-select-tag-not-selecting-default-option

hawkticehurst avatar Jan 30 '23 21:01 hawkticehurst

Thanks for your reply.

However, in the React docs it is mentioned that react offers a value property on the root of a select component, so i did expect this to work (and it does if the options are present when the component is rendered).

Regardless, the issue still seems to persist if i use the selected prop on the element that should be selected. See updated StackBlitz example: https://stackblitz.com/edit/react-ts-es5nkg?file=App.tsx

LuukVaal avatar Jan 31 '23 09:01 LuukVaal

Hey @LuukVaal!

Perhaps I'm misunderstanding your ask here, but the reason (or at least one of the big reasons) the above code isn't working is because native HTML <select> elements (and therefore the <vscode-dropdown>/<VSCodeDropdown> components because they are an implementation of select) do not have a value attribute.

To set a default value, you must add a selected attribute to the desired <option>/<vscode-option>/<VSCodeOption>.

<VSCodeDropdown>
  <VSCodeOption>option-1</VSCodeOption>
  <VSCodeOption selected>option-2</VSCodeOption> // <-- this will be the selected value
  <VSCodeOption>option-3</VSCodeOption>
</VSCodeDropdown>

Further reference: https://stackoverflow.com/questions/5589629/value-attribute-on-select-tag-not-selecting-default-option

Seems like selected attribute doesn't work at all if VSCodeOption wrapped with VSCodeDropdown, even assigned directly:

<VSCodeDropdown>
  <VSCodeOption>option-1</VSCodeOption>
  <VSCodeOption selected>option-2</VSCodeOption> // <-- this option is not selected in the dropdown and in the opened option list
  <VSCodeOption>option-3</VSCodeOption>
</VSCodeDropdown>

Just checked in your example repository for React. Same issue with "checked" attribute for VSCodeRadio wrapped with VSCodeRadioGroup.

Artyom-Safronov avatar Jun 10 '23 12:06 Artyom-Safronov

Thanks for your reply.

However, in the React docs it is mentioned that react offers a value property on the root of a select component, so i did expect this to work (and it does if the options are present when the component is rendered).

Regardless, the issue still seems to persist if i use the selected prop on the element that should be selected. See updated StackBlitz example: https://stackblitz.com/edit/react-ts-es5nkg?file=App.tsx

It works if the value prop of VSCodeDropdown is also set: https://stackblitz.com/edit/react-ts-wiinkp?file=App.tsx

Nevertheless, I think this behaviour should be reflected in the documentation.

web-devel avatar Jun 13 '23 18:06 web-devel

Thank you @web-devel! Your comment saved my life!

jdneo avatar Nov 24 '23 07:11 jdneo

I got the same problem!

drriguz avatar Jan 11 '24 15:01 drriguz

+1 For this. I don't mind that the VS Code Components here diverge from the React behavior for <select> (there's already precedent for these kind divergences), but in that case I'd like the component docs (or the React divergences docs) to show the correct way to use VSCodeDropdown.

Lucretiel avatar Feb 10 '24 00:02 Lucretiel