Skip to content

Commit 2fb88f8

Browse files
committed
feat: support suggestions listbox with option structure
1 parent 78b7230 commit 2fb88f8

7 files changed

+41
-8
lines changed

packages/main/src/ListItemGroupHeader.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { slot, property, customElement } from "@ui5/webcomponents-base/dist/decorators.js";
22
import i18n from "@ui5/webcomponents-base/dist/decorators/i18n.js";
33
import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js";
4+
import type { AriaRole } from "@ui5/webcomponents-base/dist/types.js";
5+
import toLowercaseEnumValue from "@ui5/webcomponents-base/dist/util/toLowercaseEnumValue.js";
46
import ListItemBase from "./ListItemBase.js";
57

68
import { GROUP_HEADER_TEXT } from "./generated/i18n/i18n-defaults.js";
@@ -10,6 +12,7 @@ import ListItemGroupHeaderTemplate from "./ListItemGroupHeaderTemplate.js";
1012

1113
// Styles
1214
import ListItemGroupHeaderCss from "./generated/themes/ListItemGroupHeader.css.js";
15+
import ListItemAccessibleRole from "./types/ListItemAccessibleRole.js";
1316

1417
/**
1518
* @class
@@ -39,12 +42,19 @@ class ListItemGroupHeader extends ListItemBase {
3942
@property()
4043
accessibleName?: string;
4144

45+
@property()
46+
accessibleRole: `${ListItemAccessibleRole}` = ListItemAccessibleRole.ListItem;
47+
4248
@slot()
4349
subItems!: Array<HTMLElement>;
4450

45-
@i18n("@ui5/webcomponents")
51+
@i18n("@ui5/wezbcomponents")
4652
static i18nBundle: I18nBundle;
4753

54+
get effectiveAccRole(): AriaRole {
55+
return toLowercaseEnumValue(this.accessibleRole);
56+
}
57+
4858
get groupItem() {
4959
return true;
5060
}

packages/main/src/ListItemGroupHeaderTemplate.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import type ListItemGroupHeader from "./ListItemGroupHeader.js";
22

33
export default function ListItemGroupHeaderTemplate(this: ListItemGroupHeader) {
44
return (
5-
<li
5+
<div
66
part="native-li"
7+
role={this.effectiveAccRole}
78
tabindex={this.forcedTabIndex ? parseInt(this.forcedTabIndex) : undefined}
89
class={{
910
"ui5-ghli-root": true,
@@ -19,6 +20,6 @@ export default function ListItemGroupHeaderTemplate(this: ListItemGroupHeader) {
1920
</div>
2021

2122
<slot name="subItems"></slot>
22-
</li>
23+
</div>
2324
);
2425
}

packages/main/src/ListItemGroupTemplate.tsx

+12-4
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,30 @@
1+
import type { AriaRole } from "@ui5/webcomponents-base/";
12
import type ListItemGroup from "./ListItemGroup.js";
23
import ListItemGroupHeader from "./ListItemGroupHeader.js";
34
import DropIndicator from "./DropIndicator.js";
5+
import ListItemAccessibleRole from "./types/ListItemAccessibleRole.js";
46

5-
export default function ListItemGroupTemplate(this: ListItemGroup, hooks?: { items: () => void }) {
7+
export default function ListItemGroupTemplate(this: ListItemGroup, hooks?: { items: () => void }, injectedProps?: {
8+
groupHeaderRole?: `${ListItemAccessibleRole}`,
9+
groupRole?: AriaRole,
10+
}) {
611
const items = hooks?.items || defaultItems;
12+
const groupHeaderRole = injectedProps?.groupHeaderRole || ListItemAccessibleRole.ListItem;
13+
const groupRole = injectedProps?.groupRole || "list";
714

815
return (
916
<>
1017
{this.hasHeader &&
11-
<ListItemGroupHeader focused={this.focused} part="header">
18+
<ListItemGroupHeader focused={this.focused} part="header" accessibleRole={groupHeaderRole}>
1219
{ this.hasFormattedHeader ? <slot name="header"></slot> : this.headerText }
1320
<div
21+
role={groupRole}
1422
slot="subItems"
1523
aria-owns={`${this._id}-content`}
1624
></div>
1725
</ListItemGroupHeader>
1826
}
19-
<ul class="ui5-group-li-root"
27+
<div class="ui5-group-li-root"
2028
onDragEnter={this._ondragenter}
2129
onDragOver={this._ondragover}
2230
onDrop={this._ondrop}
@@ -26,7 +34,7 @@ export default function ListItemGroupTemplate(this: ListItemGroup, hooks?: { ite
2634
{ items.call(this) }
2735

2836
<DropIndicator orientation="Horizontal" ownerReference={this}/>
29-
</ul>
37+
</div>
3038
</>
3139

3240
);

packages/main/src/SuggestionItemGroup.ts

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import customElement from "@ui5/webcomponents-base/dist/decorators/customElement
22
import slot from "@ui5/webcomponents-base/dist/decorators/slot.js";
33
import type SuggestionListItem from "./SuggestionListItem.js";
44
import ListItemGroup from "./ListItemGroup.js";
5+
import SuggestionItemGroupTemplate from "./SuggestionItemGroupTemplate.js";
56

67
/**
78
* @class
@@ -14,6 +15,7 @@ import ListItemGroup from "./ListItemGroup.js";
1415
*/
1516
@customElement({
1617
tag: "ui5-suggestion-item-group",
18+
template: SuggestionItemGroupTemplate,
1719
})
1820
class SuggestionItemGroup extends ListItemGroup {
1921
/**
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import ListItemGroupTemplate from "./ListItemGroupTemplate.js";
22
import type SuggestionItemGroup from "./SuggestionItemGroup.js";
3+
import ListItemAccessibleRole from "./types/ListItemAccessibleRole.js";
34

45
export default function SuggestionItemGroupTemplate(this: SuggestionItemGroup) {
5-
return ListItemGroupTemplate.call(this);
6+
return ListItemGroupTemplate.call(this, undefined, {
7+
groupHeaderRole: ListItemAccessibleRole.Group,
8+
groupRole: "none",
9+
});
610
}

packages/main/src/features/InputSuggestionsTemplate.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import decline from "@ui5/webcomponents-icons/dist/decline.js";
66
import List from "../List.js";
77
import ResponsivePopover from "../ResponsivePopover.js";
88
import Button from "../Button.js";
9+
import ListAccessibleRole from "../types/ListAccessibleRole.js";
910

1011
export default function InputSuggestionsTemplate(this: Input, valueStateMessage: (this: Input) => JsxTemplateResult, valueStateMessageInputIcon: (this: Input) => string) {
1112
return (
@@ -96,6 +97,7 @@ export default function InputSuggestionsTemplate(this: Input, valueStateMessage:
9697
function suggestionsList(this: Input) {
9798
return (
9899
<List
100+
accessibleRole={ListAccessibleRole.ListBox}
99101
separators={this.suggestionSeparators}
100102
selectionMode="Single"
101103
onMouseDown={this.onItemMouseDown}

packages/main/src/types/ListItemAccessibleRole.ts

+6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
*/
66
enum ListItemAccessibleRole {
77

8+
/**
9+
* Represents the ARIA role "group".
10+
* @private
11+
*/
12+
Group = "Group",
13+
814
/**
915
* Represents the ARIA role "listitem". (by default)
1016
* @public

0 commit comments

Comments
 (0)