[Bug] disabled in select option does not work

For native select elements, setting the disabled attribute on an option has no effect:

<select>
<option disabled>...</option>
</select>

Btw, is the forum the right place to submit such bugs? I thought about creating issues on github, but there are only repos dedicated to either the documentation or the examples, so I didn’t think it would fit there.

Just to piggyback on this, I’ve also found that the “multiple” attribute on native select elements doesn’t work.

<select name="cars" id="cars" multiple>
      <option value="volvo">Volvo</option>
      <option value="saab">Saab</option>
</select>

The HTML <select> does not support disabled or multiple. If you need this functionality, please use sp-dropdown, which supports both features.

1 Like

Hint for everyone: the multiple property has to go on the sp-menu, not the sp-dropdown.

Also, @kerrishotts , is there any way of keeping the dropdown opened, when selecting multiple items?
Feels like bad UX when the user has to open the dropdown 10 times to select 10 items. Maybe the component should listen for CTRL or meta-key press inside.

The whole multiple-dropdown thing took me a while to figure out correctly, so I’ll quickly share my learnings here for anyone else running into these issues.
I’m still getting a bit confused by the fact that Spectrum is praised and recommended to be used while there’s so little documentation on it (the actual UXP implementation) that we kind of have to fish in muddy waters.

Anyways, the UXP examples show the use of onChange(evt => console.log(evt.target.selectedIndex) to retrieve the index of the selected item. For multiple selectable options (sp-menu-items), this doesn’t help a lot as it always returns the index of the first selected option.

Logging evt.target.__proto__ finally gave me an idea of which properties the sp-dropdown object actually has:

So at least there’s a getter called selectedOptions, which returns the sp-menu-item elements whose values we can the retrieve and parse.

If you’re using React, you’re probably storing selected options in some kind of state. In my case it looks like this:

const state = {
  someObj: {
    a: false,
    b: false,
    c: false,
  }
}

This results in a setup like the following:

<WC onChange={e => {
  const selectedKeys = e.target.selectedOptions.map(({value}) => value)
  const updated = Object.keys(this.state.someObj).reduce((obj,key) => ({...obj, [key]:selectedKeys.includes(key)}),{});
  this.setState({someObj: updated})
}}>
  <sp-dropdown placeholder="Make a selection...">
    <sp-menu multiple slot="options">
      {
        Object.keys(this.state.someObj).map(key => {
          return <sp-menu-item selected={this.state.someObj[key] ? true : null} key={key} value={key}>{key}</sp-menu-item>
        })
      }
    </sp-menu>
  </sp-dropdown>
</WC>

However, if your state looks more like that (using arrays)…

const state = {
  options: ["a", "b", "c"],
  selectedOptions: [],
}

… the setup would probably be similar to:

<WC onChange={e => {
  const selectedOptions = e.target.selectedOptions.map(({value}) => value)
  this.setState({selectedOptions})
}}>
  <sp-dropdown placeholder="Make a selection...">
    <sp-menu multiple slot="options">
      {
        this.state.options.map(opt => {
          return <sp-menu-item selected={this.state.selectedOptions.includes(opt) ? true : null} key={opt} value={opt}>{opt}</sp-menu-item>
        })
      }
    </sp-menu>
  </sp-dropdown>
</WC>


So far so good, but there’s still a problem:

The selected property of a sp-menu-item seems to have been designed for non-multiple sp-menus only. It overwrites the current selected value so that there’s always just one selected item at a time, which prevents me from prefilling the dropdown with the initial values.

One more thought:
Maybe the sp-dropdown / sp-menu should expose more events than just a change event? If it provided a more specific onSelect(opt), state updates would be a lot easier as only the single changed option would have to be updated.

Edit: Another thing I just noticed:
When there’s more than one option selected, the dropdown text will only display the first selected options name. From a usability point of view that’s quite problematic as the user has no visual feedback of what’s selected and if his selection worked, other than reopening the dropdown to double-check. Commonly it should show something like “Option1, Option2” or “2 Selected”.

1 Like

Are there any news regarding these 3 points?

Another bug / missing feature for sp-menu: It’s not possible to pre-select multiple sp-menu-items. If more than one element has the selected attribute, only the last one will be selected at the start.
Additional menu items can only be selected via user interaction :confused:

1 Like

Hi @simonhenke , thank you for noting these bugs with sp-menu and sp-dropdown. I’ll be sure to pass these notes on to the right people. And this answer is late but the forums is a great place to file bugs you notice!

1 Like

Hello everyOne!
is this issue resolved now?
Since I still facing the issue.

I had the same issue; I tried to use a wrapper as described here. But nothing worked. Out of desperation, I tried adding an onClick on the sp-menu-item elements of the sp-picker, and it worked.

Also, if you’re looking to use multiple selection, adding multiple=“true” to sp-menu seems to do the trick. Then, if using react, you can add a useRef onto the sp-menu to find the selected options.

Here’s an example of sp-picker that works for me:

<sp-picker>
  <sp-label slot="label">Pick your option(s)</sp-label>
    <sp-menu ref={pickerRef} multiple="true" >
        {elementsList.map(element => (
            <sp-menu-item key={element} value={element} onClick={handleSelect}>
              {element}
            </sp-menu-item>
        ))}
    </sp-menu>
</sp-picker>

Here’s the handleSelect:

const handleSelect = () => {        
        let selectedOptions = [];
        for (const menuItem of pickerRef.current.selectedOptions) {
            selectedOptions.push(menuItem.value);
        }   
        console.log(selectedOptions)
    };

Don’t forget to add useRef to your react import and declare the ref before using it. I hope this helps.

Any updates on this? it would be great to get this logged as a bug if not already done.
The multiple property on the sp-menu still doesn’t allow us to initialize multiple sp-menu-items as selected.
Thanks!

That you don’t seem to be able to set multiple sp-menu-items as selected has tripped me up to.

I would like to show the user a list of items from which they can choose multiple items. I’d like to give the user “Select All” and “Select None” buttons so they can easily select every item or clear the list of selected items.

I can almost do what I want with the <sp-menu> widget (multiple clicks selecting multiple items works OK), but I haven’t found a way to implement Select All. (BTW I don’t use React or SWC.)

Unless anyone has a clever trick for selecting multiple sp-menu-items in code, I guess I’ll have to write my own web component to achieve what I want.