Combo Specification - IgniteUI/igniteui-webcomponents GitHub Wiki

Combo Specification

Contents

  1. Overview
  2. User Stories
  3. Functionality
  4. Test Scenarios
  5. Accessibility
  6. Assumptions and Limitations
  7. References

Owned by

Web Development Team

Developer Name

  1. Simeon Simeonoff
  2. Silvia Ivanova

Designer Name

  1. Vasil Tashkov

Requires approval from

  • Silvia Ivanova | Date:
  • Svilen Dimchevski | Date:

Signed off by

  • Radoslav Mirchev | Date: 05-Dec-2022
  • Radoslav Karaivanov | Date: 06-Dec-2022

Revision History

Version Users Date Notes
1 Simeon Simeonoff, Vasil Tashkov 05/12/2022 Initial spec
2 Simeon Simeonoff 18/01/2023 Minor updates
3 Radoslav Karaivanov 08/06/2023 Updated filter options
4 Simeon Simeonoff 20/06/2023 Updated event details
5 Radoslav Karaivanov 09/01/2024 Added grouping section
6 Radoslav Karaivanov 10/01/2024 Dropped items sort when grouping

Objectives

The Combo component is similar to the Select component in that it provides a list of options from which the user can make a selection. In contrast to the Select component, the Combo component displays all options in a virtualized list of items, meaning the combo box can simultaneously show thousands of options, where one or more options can be selected. Additionally, users can create custom item templates, allowing for robust data visualization. The Combo component features case-sensitive filtering, grouping, complex data binding, dynamic addition of values and more.

End-to-end user experience prototype

Elaborate more on the multi-facetted use cases

Developer stories:

  • Story 01: I want to be able to insert a component that allows, upon clicking, the showing of a list of options, so that the users of my app can select item(s) from that list.
  • Story 02: I want to be able to easily list all items in a way that separates their underlying value from the displayed option, so that I can separate my model from my view.
  • Story 03: I want to be able to initialize the selected value(s) from the list of options, so that I can pre-fill the input with default data.
  • Story 04: I want to be able to label the input, so that I can communicate what the expected input value should be.
  • Story 05: I want to be able to provide a description or additional text as a secondary label, so that I can communicate what the expected input value should be in greater detail.
  • Story 06: I want to be able to provide a placeholder text, so that I can showcase a sample input value or provide a call-to-action message.
  • Story 07: I want to be able to show icons at the beginning/end of the component, so that I can communicate the meaning of the input data clearer.
  • Story 08: I want to be able to customize the size of the component, so that I can better manage the layout of my app.
  • Story 09: I want to be able to see the list of items at all times, regardless of where I place the component in the layout of my app.
  • Story 10: I want to be able to customize visual style of the component, so that it can fit the design language of my app.
  • Story 11: I want to be able to disable the component, so that I can control the flow of information based on design requirements/constraints.
  • Story 12: I want to pad the list of items with a header and/or footer, so that I can provide additional information/functionality in the provided area(s).
  • Story 13: I want to bundle the list of options into labeled groups, so that I can control the properties of all items in the group at the same time.
  • Story 14: I want to be able to mark the component as required, so that I can enforce the collection of data from the users of my app.
  • Story 15: I want to be able to control the validity of the component, so that I can have better control of whether the selected data is valid or not.
  • Story 18: I want to be able to use the component in the context of the <igc-form> component, so that I can collect its data alongside other inputs.
  • Story 19: I want to be able to select multiple items from the list of options, so that I can aggregate information as a list of values.
  • Story 20: I want to be able to mark the component as read-only, so that users can be informed about a default selection.
  • Story 21: I want to be able to provide a collection of values as a data object, so that I don't have to declaratively describe thousands of options in markup.
  • Story 22: I want to be able to specify which property in an object should be used as the text value, so that I can separate the actual value from what is displayed to the end user.
  • Story 23: I want to be able to specify which property in an object should be used as the data value, so that I can separate the actual value from what is displayed to the end user.
  • Story 24: I want to be able to specify which property in an object should be used as the filter value, so that I can filter by value different from what is displayed to the end user.
  • Story 25: I want to be able to control how filtering behaves with text containing diacritics/accented symbols and how the component should match them.
  • Story 26: I want to be able to select falsy values(0, false, '', null, NaN).
  • Story 27: I want to be able to specify a template for individual items, so that I can better customize the end-user experience.
  • Story 28: I want to be able to quickly clear the selection made by the end user, so that I can provide a way to start the selection-process anew.
  • Story 29: I want to be able to change the UI elements regarding clearing/toggling of the selection, so that I can better customize the end-user experience.
  • Story 30: I want to be able to modify the collection of values at runtime, so that I don't have to reinitialize the component every time the data changes.
  • Story 31: I want to be able to filter the data of the dropdown at runtime, so that I can provide better end-user experience.
  • Story 32: I want to be notified when the value of the input has changed, so that I can react to it in the business logic of my app.
  • Story 33: I want to be notified when the dropdown of the input is shown/hidden, so that I can react to it in the business logic of my app.
  • Story 34: I want to be notified when the user fires keyboard events inside the input's dropdown, so that I can react to it in the business logic of my app.
  • Story 35: I want to show the list of data in a performant way, so that I can present a large set of data for selection to the end-user.
  • Story 36: I want to evaluate the validity state of the component, so that I can notify the end-user when a field is required.

A future release will implement the following Developer Story:

  • Story 37*: I want to be able to provide a remote collection of values as a data object, so that I don't have to declaratively describe thousands of options in markup.

End-user stories:

  • Story 01: I want to be able to select one or more items from a list of options, so that I can fill in an input from a list of pre-defined values.
  • Story 02: I want to be able to identify the selected items from the list of options, so that I can know which items are the currently selected one.
  • Story 03: I want to be able to navigate and select the list of options using my keyboard and mouse, so that I can use the best input method for me.
  • Story 04: I want to be able to filter list of options by a keyword, so that I can limit the number of choices presented to me.
  • Story 05: I want to be able to have a clear distinction between selected and unselected items, so that I can make better decisions about my selection.
  • Story 06: I want to be able to have a clear distinction between selected and unselected items, so that I can make better decisions about my selection.
  • Story 07: I want to be able to easily clear my selection, so that I can quickly restart the selection process.
  • Story 08: I want my browser to quickly load the list of options, so that I can quickly start selecting items.
  • Story 09: I want to be able to change the search case sensitivity, so that I can better identify the items I'm looking for.
  • Story 10: I want to be able to see the text I'm typing when the combo is on focus, so that I am certain of the option I am searching for.
  • Story 11: I want to be able to see the list of options upon clearing my selection, so that I can skim over the available options.

Describe behavior, design, look and feel of the implemented feature. Always include visual mock-up

3.1. End-User Experience

** Integration scenarios or functionality with other features/components prototype > ** End-to-end user experienceprototype > ** Prepared design files for styling e.g. interplay with features and light/dark variants design hand-off

3.2. Developer Experience

The following example illustrates how the Combo component can be used in a Lit application.

import { html, render } from 'lit';
const cities = [
  {
    name: 'London',
    id: 'UK01',
    region: 'EMEA',
  },
  {
    name: 'Sofia',
    id: 'BG01',
    region: 'EMEA',
  },
];

const combo = document.querySelector('igc-combo');

// Get the item and the visual index(filter-bound);
const itemTemplate = (item) => {
  return html`
    <div>
      <span>${item.name} (${item.id})</span>
    </div>
  `;
};

// Get the item and the visual index(filter-bound);
const groupHeaderTemplate = (item) => {
  return html`
    <div>
      <span>${item.region}</span>
    </div>
  `;
};

combo.itemTemplate = itemTemplate;
combo.groupHeaderTemplate = groupHeaderTemplate;

const app = html`
  <igc-combo
    .data=${cities}
    label="Cities"
    display-key="name"
    value-key="id"
    value='["BG01", "BG02"]'
    group-key="region"
    group-sorting="desc"
    autofocus
    autofocus-list
    placeholder="Pick a city"
    placeholder-search="Search for a city"
    case-sensitive-icon
    disable-filtering
    outlined
    required
  ></igc-combo>
`;

render(app);

3.3. Keyboard Navigation

  • To trigger any keyboard navigation event, the <igc-combo> must be in focus. The list of options can be opened by pressing on any character key, the Down key, or the Alt + Down keys, as well as with a mouse click. Using the Down arrow key will focus(activate) the next item in the list until the end of the list of options is reached, in which case the keyboard navigation will do nothing upon pressing the aforementioned key. The Up arrow key will focus(activate) the previous item in the list of options until the beginning of the list is reached. If the user continues pressing on the up key when in the beginning of the list of options, the dropdown closes and the focus returns to the combo input.
  • While the dropdown menu is open, pressing the Home key focuses(activates) the first item in the list of options. Conversely, the End key focuses(activates) the last item in the list of options. While an item is active, pressing the Space keys will select/deselect the active item. The Enter key behaves similarly, but will also close the dropdown menu upon selection/deselection.
  • Pressing the Esc key closes the list of options without changing the selection.
  • When adding custom values is allowed, a new item can be added while the Add Item button is on focus by pressing the Enter key.

Keyboard navigation when the list of options is not visible:

Keys Description
Down / Alt + Down Opens the list of options.

Keyboard navigation when the list of options is visible:

Keys Description
Down Activates the next item from the list of options.
Up Activates the previous item from the list of options. If the first item is already active it will focus the input.
Space Selects the active item.
Enter Selects the active item and closes the list of options.
Home Activates the first item from the list of options.
End Activates the last item from the list of options.
Esc Closes the list of options.
Tab / Shift + Tab Closes the list of options.

Keyboard navigation when the Add Item button is on focus:

Keys Description
Enter Adds a new item and returns focus to the input.
Up Returns focus to the input.

Additional functionality: Typing while the component is in focus will filter the list of items for those that most closely match the current user input.

3.4. Grouping

  • When a group key is set, the igc-combo will group its items based on that key.
  • Items which cannot be resolved based on the passed group key (that is T[groupKey] returning null or undefined) will be aggregated into a group named "Other".
  • When grouping is enabled, developers may control the sorting directions of the groups through the groupSorting property. Defaults to 'asc' (ascending).
  • The sorting is locale aware.

API

FilteringOptions

Name Description Type Default value
filterKey The key in the data source used for filtering the list of items. keyof T Defaults to the combo displayKey.
caseSensitive Whether the filter operations should be case sensitive. Boolean false
matchDiacritics Whether the filter operations should distinguish between accented letters and their base counterparts. Boolean false

Properties

Name Description Type Default value Reflected
data The data source used to render items. T[] - false
value Gets/sets the selected items in the combo input. Values<T>[] - -
display-key Determines which column in the data source is used as the display value. Keys<T> - false
value-key Determines which column in the data source is used as the value. Keys<T> - false
group-key The item property by which items should be grouped inside the items list. Not usable if data is not of type Object[]. Keys<T> - false
group-sorting Sets the sorting direction for the groups. asc | desc | none asc false
single-select Disables multi-item selection and moves filtering prompt to the main input. Boolean false true
filtering-options Allows passing configuration of filterKey, caseSensitivity. FilteringOptions - false
disable-filtering Disables the filtering of the list of options. Has no effect when single-select is set. Boolean false false
case-sensitive-icon Allows case-sensitive search to be controlled by the end-user. Has no effect when single-select is set. Boolean false true
open Opens the list of items by default. Boolean false false
autofocus Automatically focuses the component on page load. Boolean false false
autofocus-list The list of options gets focused upon opening. Has no effect when single-select is set. Boolean false false
name Sets the name of the component. string - false
label Sets the label of the component. string - false
placeholder Sets the placeholder of the component. string - false
placeholder-search Sets the placeholder of the input in the dropdown menu. Has no effect when single-select is set. string - false
outlined Sets material-themed inputs to outlined style mode. Boolean false true
disabled Sets the disabled state of the component. Boolean false true
required Sets the required state of the component. Boolean false true
invalid Sets the validity of the component. Boolean false true

Scheduled for implementation:

Name Description Type Default value Reflected
custom-values Allows the users to add own values to the list of data. Boolean false false

Methods

Name Description Return type Parameters
toggle Toggles the list of options. void -
show Shows the list of options. void -
hide Hides the list of options. void -
focus Focuses the component. - options: FocusOptions
blur Blurs the component. void -
select Selects the defined items. If items is an empty array, all items are selected. void items?: <T>[]
deselect Deselects the defined items. If items is an empty array, all items are deselected. void items?: <T>[]
checkValidity Marks the component as invalid if it doesn't satisfy the validation constraints. boolean -
reportValidity Returns true if the component satisfies the validation constraints. boolean -
itemTemplate The custom template, if any, that should be used when rendering items in list of options. TemplateResult value<T>
groupHeaderTemplate The custom template, if any, that should be used when rendering header items in list of options. TemplateResult value<T>
selection Gets the current value/selection as array of objects. <T>[] -

Scheduled for implementation:

Name Description Return type Parameters
filterFunction Gets/sets the custom filtering function used for the combo. The passed function can be async. Function collection: T[], searchValue: any, options: FilteringOptions
navigateTo Navigates to the item with specified value. IgcSelectItem value<T>

Events

Name Description Cancelable Parameters
igcFocus Emitted when the component gains focus. false
igcBlur Emitted when the component loses focus. false
igcOpening Emitted before the list of options is opening. true
igcOpened Emitted after the list of options is opened. false
igcClosing Emitted before the dropdown is closing. true
igcClosed Emitted after the list of options is closed. false
igcChange Emitted after selection is done on blur. true {newValue: string[], items: T[], type: 'selection' | 'deselection' | 'addition' }

Scheduled for implementation:

Name Description Cancelable Parameters
igcNewCustomValue Emitted when an item is being added to the data collection. true {oldCollection, itemAdded, newCollection}
igcFiltering Emitted when the list is being filtered. true {searchTerm}
igcFiltered Emitted when the list is filtered. false {searchTerm, newCollection}

CSS Parts

The <igc-combo> component provides the following CSS parts:

Name Description
label The encapsulated text label.
input The main input field.
native-input The native input of the main input field.
prefix The prefix wrapper.
suffix The suffix wrapper.
toggle-icon A toggle icon wrapper.
clear-icon A clear icon wrapper.
case-icon A case-icon wrapper that renders content inside the suffix of the filter-input.
helper-text A helper-text wrapper that renders content below the target input.
search-input The search input field.
list-wrapper A list-wrapper that holds the filter-input and the igc-combo-list component.
list The list of options (igc-combo-list).
item An item-wrapper that holds the content of the combo items.
group-header A wrapper that holds the text content of the group headers.
active A wrapper that holds the content of the combo active items.
selected A wrapper that holds the content of the combo selected items.
checkbox Represents each checkbox of each list item.
checkbox-indicator Represents the checkbox indicator of each list item.
checked Appended to checkbox parts list when checkbox is checked.
empty The container holding the empty template.

Slots

The <igc-combo> component provides the following slots:

Name Description
header Renders the header element.
footer Renders the footer element.
prefix Renders the prefix element.
suffix Renders the suffix element.
helper-text Renders the helper-text element.
toggle-icon Renders the toggle-icon element.
clear-icon Renders the clear-icon element.
empty Renders when no items are shown in the dropdown.

Scheduled for implementation:

Name Description
add-item Renders the Add Button UI in the dropdown.
loading Renders the loading container.

The <igc-combo-item> component provides the following slots:

Name Description
(default) Renders the item's content.

The <igc-combo-header> component provides the following slots:

Name Description
(default) Renders the header's content.

ARIA Support

  • <igc-combo> - role combobox.
    • aria-owns - encapsulated container holding all items.
    • aria-haspopup
    • aria-describedby - helper-text.
    • aria-disabled - set to the disabled attribute of the component.
  • <igc-combo-item>(implicit)
    • role - option.
    • aria-selected - depends on its selection status.
  • <igc-select-group>(implicit)
    • role - group
  • encapsulated container holding all items - role="listbox"

RTL Support The component should provide full RTL support by default.

Assumptions Limitation Notes

Specify all referenced external sources

⚠️ **GitHub.com Fallback** ⚠️