Skip to content

feat(ui5-select): add ui5-option-group component for grouped options - #13913

Open
plamenivanov91 wants to merge 3 commits into
mainfrom
select-grouping-final
Open

feat(ui5-select): add ui5-option-group component for grouped options#13913
plamenivanov91 wants to merge 3 commits into
mainfrom
select-grouping-final

Conversation

@plamenivanov91

Copy link
Copy Markdown
Contributor

Introduces ui5-option-group, a new public component that allows grouping options inside ui5-select, matching the ComboBox's ui5-combobox-item-group API pattern.

Key changes:

  • New ui5-option-group component extending ListItemGroup, with individualSlots: true and ARIA group semantics (role="group", aria-label, aria-roledescription)
  • Select._flatOptions getter flattens grouped + ungrouped options for all navigation and selection logic
  • Per-group aria-setsize/aria-posinset injected via _forcedSetsize and _forcedPosinset on Option, rendered via ListItemBaseTemplate
  • Hidden live-region span on the Select trigger announces option count and group count on focus (aria-describedby)
  • IOptionGroup interface exported from Select.ts for consumers
  • Website docs sample added (OptionGroups)

JIRA: BGSOFUIPIRIN-7094

Introduces ui5-option-group, a new public component that allows
grouping options inside ui5-select, matching the ComboBox's
ui5-combobox-item-group API pattern.

Key changes:
- New ui5-option-group component extending ListItemGroup, with
  individualSlots: true and ARIA group semantics (role="group",
  aria-label, aria-roledescription)
- Select._flatOptions getter flattens grouped + ungrouped options
  for all navigation and selection logic
- Per-group aria-setsize/aria-posinset injected via _forcedSetsize
  and _forcedPosinset on Option, rendered via ListItemBaseTemplate
- Hidden live-region span on the Select trigger announces option
  count and group count on focus (aria-describedby)
- IOptionGroup interface exported from Select.ts for consumers
- Website docs sample added (OptionGroups)

JIRA: BGSOFUIPIRIN-7094
@plamenivanov91
plamenivanov91 requested a review from IlianaB August 11, 2026 14:02
@plamenivanov91
plamenivanov91 deployed to netlify-preview August 11, 2026 14:02 — with GitHub Actions Active
@sap-ui5-webcomponents-release

Copy link
Copy Markdown

@plamenivanov91
plamenivanov91 deployed to netlify-preview August 12, 2026 09:48 — with GitHub Actions Active
@plamenivanov91
plamenivanov91 deployed to netlify-preview August 12, 2026 12:42 — with GitHub Actions Active
@github-actions

Copy link
Copy Markdown

👋 Heads-up: dev close is in effect

Thanks for the contribution! This repository is currently in dev close ahead of release 2.26 (scheduled 2026-08-26, UTC). See the release schedule for the full timeline.

This PR appears to introduce public-API changes (detected by diffing the Custom Elements Manifest against the latest published version on npm):

@ui5/webcomponents

  • ➕ added element: OptionGroup
  • ➕ added property: headerAccessibleName
  • ➕ added property: headerText
  • ➕ added property: wrappingType
  • ➕ added event: move
  • ➕ added event: move-over
  • ➕ added slot: default
  • ➕ added slot: header
  • ➕ added CSS part: header
  • ➕ added CSS part: title
  • ➕ added attribute: header-accessible-name
  • ➕ added attribute: header-text
  • ➕ added attribute: wrapping-type
  • ➕ added interface: IOption
  • ➕ added interface: IOptionGroup
  • 🔄 changed attribute value-state (type)

Could you please hold off on merging into main until the release ships? Public-API changes are best landed in the next dev cycle so they don't slip into the release at the last minute. Once the release is out, this PR is good to go.

If this change must ship in the current release, please request a review from one or two members of @UI5/ui5-team-webc so the team can sign off explicitly.

💬 False positive? If you believe this PR doesn't actually change the public API (e.g. only internal refactoring, or an entry the detector mis-attributed), please reply on this thread — your feedback helps us improve the detection during this trial run.

Posted automatically by the Dev Close Notice workflow.

* @constructor
* @extends ListItemGroup
* @public
* @since 2.10.0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be 2.26.0

*/
_applyAutoSelection() {
let selectedIndex = this.options.findLastIndex(option => option.selected);
let selectedIndex = this._flatOptions.findLastIndex(option => option.selected);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we cache the flatOptions here, as on each call of the getter there is a mapping, flatting and instance check?

const options = this._flatOptions;

_select(index: number) {
const selectedIndex = this._selectedIndex;
if (index < 0 || index >= this.options.length || this.options.length === 0) {
if (index < 0 || index >= this._flatOptions.length || this._flatOptions.length === 0) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cache flatOptions also here, as there are 5 call in this method.


_applyFocusToSelectedItem() {
this.options.forEach(option => {
this._flatOptions.forEach(option => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and cache flatOptions again here

const group = item as IOptionGroup;
group.items.forEach((option, idx) => {
option._forcedSetsize = group.items.length;
option._forcedPosinset = idx + 1;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as UI5, according to Figma:
aria-setsize should be the total count of options and aria-posinset should be the individual position in the whole set

@IlianaB IlianaB left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as UI5:
Underline (border) of group header is missing here.

And I wonder: should a flat option also have a aria-posinset and aria-setsize ... sounds pretty logical to me. But we can ask ACC experts on this.

responsivePopoverHeader: {
"display": this.options.length && this._listWidth === 0 ? "none" : "inline-block",
"width": `${this.options.length ? this._listWidth : this.offsetWidth}px`,
"display": this._flatOptions.length && this._listWidth === 0 ? "none" : "inline-block",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cache flatOptions.length

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants