[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:

image

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”.

Are there any news regarding these 3 points?