[ui5-side-navigation]: javascript exception on tablet
Bug Description
On Chrome with dev tools simulating a tablet (iPad Air).
Open this test page https://sap.github.io/ui5-webcomponents/nightly/packages/fiori/test/pages/NavigationLayout.html
There is an error in the console.
Uncaught (in promise) TypeError: Cannot read properties of null (reading 'classList')
at bundle.esm-BjSpMYlu.js:472:4680
at Array.reduce (
Affected Component
No response
Expected Behaviour
No response
Isolated Example
No response
Steps to Reproduce
No response
Log Output, Stack Trace or Screenshots
No response
Priority
None
UI5 Web Components Version
2.9.0-rc.0
Browser
Chrome
Operating System
No response
Additional Context
No response
Organization
No response
Declaration
- [x] I’m not disclosing any internal or sensitive information.
The issue will be addressed in our samples and test pages with #11203, and a general solution will be deliberated by the Core team.
Hello colleagues @UI5/ui5-team-ctr-rod,
I investigated the issue a bit, and to me the problem seems related to the component itself.
It appears that the root cause is in
https://github.com/UI5/webcomponents/blob/main/packages/fiori/src/SideNavigationGroup.ts#L81, specifically the use of the exclamation mark (!) to assert that the separator is not nullish. I would assume that we can safely use the non-null assertion operator only when the overflowItems getter is used strictly within the context of SideNavigationGroup. If it is accessed from outside that context, I would recommend reworking the getter to return Array<HTMLElement | null>, because a custom element may be defined without a shadow root. In such cases, the slot elements are correctly assigned to their respective slots, and the accessors return the expected values, but queries on the shadow root will return null.
The library itself waits for all custom elements used in SideNavigation slots to be defined in order to use their metadata APIs, but query selectors may still return unexpected or inconsistent values.
With the current implementation, the following code behaves as shown below:
get overflowItems(): Array<HTMLElement> {
const separator1 = this.shadowRoot!.querySelector<HTMLElement>(".ui5-sn-item-separator:first-child")!; // => returns null
const separator2 = this.shadowRoot!.querySelector<HTMLElement>(".ui5-sn-item-separator:last-child")!; // => returns null
const overflowItems = this.items.reduce((result, item) => {
return result.concat(item.overflowItems);
}, new Array<SideNavigationItem>()); // => returns array of SideNavigationItem
return [separator1, ...overflowItems, separator2]; // => [null, ...Array<SideNavigationItem>, null]
}