Calcite-components: Component: Combobox

Created on 18 Jun 2019  路  42Comments  路  Source: Esri/calcite-components

In a recent meeting we discussed some of the behavior around "select" and "dropdown" type elements discussed in:

In the end we settled on implementing something like the multiple select/filter dropdown @macandcheese proposed in https://github.com/ArcGIS/calcite-components/issues/2#issuecomment-500260665

Example

The purpose of this component would be to allow a use to pick an item or set of items from a list

In order to accommodate various use cases we should incorporate the following options.

  • Permanently open (with user defined height) or open on select - for charting components
  • Show/hide chips - for charting components
  • Chip position (inline, after list, hidden)
  • Filterable or not filterable - for long lists
  • Add arbitrary values - for tag lists

Similar to other components that implement form controls I would REALLY like this to look like:

<calcite-super-select>
  <select name="tags" multupile>
    <option value="Test">
    <option value="Foo">
    <option value="Bar">
  </select>
</calcite-super-select>

I also think this could be called something more reasonable like <calcite-combo-select>

Proposed API

Aria role: Listbox. https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/listbox_role

/**
 * @slot - A slot for adding `calcite-select-option`s that will appear inside the component.
 */
CalciteSelect { // could this wrap a native <select> element?
  // default title displayed when no value is selected.
  @Prop({reflect: true}) defaultTitle!: string;

  @Prop({ reflect: true }) disabled = false;
  @Prop({ reflect: true }) loading = false;

  // Ability to select multiple or single values.
  // Multiple will display the select as a list without the menu.
  @Prop({ reflect: true }) multiple = false;

  @Prop({ reflect: true }) theme: "light" | "dark" = "light";

  // Version 2 props:
  // @Prop({ reflect: true }) filter = false; // V2
  // @Prop({ reflect: true }) chips = false; // V2
  // @Prop({ reflect: true }) chipValues = []; // V2
  // @Prop({ reflect: true }) chipPosition = "inline" | "after" | "list"; // V2

  @Method()
  async setFocus() {}

  @Event() calciteSelectChange: EventEmitter;
}

/**
 * @slot icon - A slot for adding content that will appear on the leading side of the option.
option.
 */
CalciteSelectOption { // could this wrap a native <option> element?
  @Prop({ reflect: true }) value!: string;
  @Prop({ reflect: true }) title!: string;
  @Prop({ reflect: true }) selected: boolean = false;

  @Event() calciteSelectOptionChange: EventEmitter;
}

Example

<calcite-select>
  <calcite-select-option value="1" title="hello" selected></calcite-select-option>
  <calcite-select-option value="2" title="hi">
    <calcite-icon slot="icon" icon="x">
  </calcite-select-option>
  <calcite-select-option value="3" title="parent">
    <!-- nesting is allowed for indentation like a list item -->
    <calcite-select-option value="4" title="child"></calcite-select-option>
  </calcite-select-option>
</calcite-select>
design discussion help wanted new component question

All 42 comments

Thanks for opening - working with Mike on finalizing designs for this. Dependent on https://github.com/ArcGIS/calcite-components/issues/47.

In ArcGIS Online, the current tags widget requires the user to type something first to get the autocompleted tags. There is feedback that users want to see a list of existing tags, and then decide whether to create a new tag. This will help reduce unnecessary/repeated tags.

The tags widget in in Notion seems to be a good reference:

Screen Shot 2019-07-24 at 4 11 34 PM

image

Chips will be a requirement for this https://github.com/Esri/calcite-components/issues/47

We have a need for this component as well with a few modifications:

Modifications

  • The select option should have a slot to take custom content on the leading and trailing side.

    • This will allow for a thumbnail or control on either side of the option.

  • The select box on the dark theme should be dark as well as the dropdown
  • The selected visual state could be defined by a background color and/or a border on the item instead of a dot.

Notes

2019-12-31_11-28-50_565

Our use case doesn't need multiple but it wouldn't hurt to have it.

It would also be good to just have the dropdown part of the component available for use within the calcite-value-list and calcite-pick-list or these components could be deprecated.

cc @asangma

Permanently open (with user defined height) or open on select - for charting components

I think we could have the permanently open as its own component that this one uses internally.

Maybe calcite-select-menu uses calcite-select-list internally?

Or it could just be an option like proposed. Maybe like appearance: "list" | "menu"?

Added API to top.

dzine
image

Should we leave the "summary" portion out for now? I see it in both the examples that @janett-baresel included in https://github.com/Esri/calcite-app-components/issues/383.

Thanks for updating the api @driskull.

re: chips
Per recent discussion in the sync meeting, we thought it would be good to separate out the chips requirement. It could be its own component that interacts with this select component or something else. @macandcheese cool cool?

Yes, agreed! in fact they already have an open issue :) - https://github.com/Esri/calcite-components/issues/47.

Lots of use cases for chips to exist on their own - in tandem with tree nav selected items, marketplace type filtering experiences, "user tags with avatars", etc. Should support icon, image, "click to close", etc.,

This component would just leverage those I think.

@asangma if we get some text and thumbnail, it would already be good. We can see how we can extend the summary part inside SV if its out of scope for you right now.

Edit: saw summary in attached screenshots. I think we already provide "title" and "subtitle" slots in accordion title etc, we could provide it here but with less strict style overrides to allow the font used in examples attached.

Sounds like we need a "selected-appearance-type" attribute to allow selection between dot, check, border, or outline (probably something useful for other components too like dropdown and tree nav that have a selected state, down the road), in a standardized way across components.

Sounds like we need a "selected-appearance-type" attribute to allow selection between dot, check, border, or outline

I think a slot would be better so we can handle the color ramp use case.

Would that be handled by slot for thumbnail?

Or does the selected outline ring change based on color ramp?

I just meant being able to choose the manner in which a selected item is highlighted. Could be a "none" option for those that want greater customization but I think we want to give folks matching styles to the other "selected items" in components if they don't need that.

Couple more gotchas:

Looks like we'll need options to,

"remove from list when selected" - once an item becomes an appended chip, remove it from the filterable list of choices (and reciprocally, return to list when chip is dismissed), and,

"create chip from string" - and then emit that in an event for an app to use.

Based on our wonderfully consistent tags and category options currently on the Content page in Online:

Screen Shot 2020-01-10 at 8 11 28 AM

Requirements from the Developers site tags component

  • Generally follow the WCAG guidelines for combobox
  • Display of the component should be a text box with chips for the selected items.
  • Chips display a "X" icon to deselect the item represented by that chip.
  • A list of available options should appear when the input is focused.
  • Keyboard navigation can be used in the list to select items (up down enter)
  • If the input in empty and the user hits delete the last selected item is selected
  • Chips can be navigated and deselected by keyboard (left right enter delete)
  • When a chip is removed by keyboard the next chip is selected
  • Add an options so users can hit "Enter" and add a new item to the available options. This is selected by default.

There are lots of detailed interactions in the WCAG document above which we implemented for the developers site. For example hitting Esc in the text box clears the selection, focus never leaves the text box, tons of ARIA attributes ect...

"Lookup" terminology here seems useful, this differentiation and nomenclature makes sense to me if we want something better than "super select"

https://uniform.hudl.com/components/selects/design

We spoke briefly at the end of the meeting about the name of this component. Super select may not be the best descriptor. What about calcite-combobox or perhaps calcite-tag-manager? Any ideas?

Of the above, I prefer combobox or "lookup" from above linked example. Tag manager sounds perhaps too specific to a workflow.

I just meant being able to choose the manner in which a selected item is highlighted. Could be a "none" option for those that want greater customization but I think we want to give folks matching styles to the other "selected items" in components if they don't need that.

You're right. that sounds good.

What about calcite-combobox or perhaps calcite-tag-manager? Any ideas?

Why not just call it a calcite-select which is an enhanced selection component that does more than a native select element?

@patrickarlt @macandcheese @asangma I wanted to bring up a thought I had on the API in regards to implementing the list values. I think the assumption up until now has been that it would be done via slotted content. We could go that route, but I wanted to bring up the option of having the data supplied as rich data (an array of objects). The combobox could then render the list internally in its own render function.

My reasoning behind this is that the combobox needs the list data in a rich data format in order to effectively do the filtering. Using slotted content would mean we'd have to parse that HTML. It would also be easier to manage the display of which items and parents are selected or partially selected if the combobox had control over the rendering of the list.

If this is difficult to visualize, we could setup a meeting to share screens, or I could proceed in this fashion and we could review in the PR stage.

option of having the data supplied as rich data (an array of objects).

I think this would be inconsistent with the way other components work. If we can do it using child components that would be ideal.

One requirement we have for Calcite-Select is to show Field Type as in this example

Screen Shot 2020-01-15 at 1 45 18 PM

@patrickarlt keyboard stepping works with tab and shift-tab at the moment. Is it necessary for the arrow keys to mimic that behavior as well?

Is it necessary for the arrow keys to mimic that behavior as well?

I think so. Its a requirement of the listbox role which is what we're pretty much going for.

https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/listbox_role

ARIA: listbox role
The listbox role is used for lists from which a user may select one or more items which are static and, unlike HTML