diff --git a/packages/main/src/components/ObjectPage/ObjectPage.cy.tsx b/packages/main/src/components/ObjectPage/ObjectPage.cy.tsx index 9cb10f4d980..e6b46ff9bad 100644 --- a/packages/main/src/components/ObjectPage/ObjectPage.cy.tsx +++ b/packages/main/src/components/ObjectPage/ObjectPage.cy.tsx @@ -1,7 +1,7 @@ import '@ui5/webcomponents-icons/dist/AllIcons.js'; import '@ui5/webcomponents-fiori/dist/illustrations/NoData.js'; import type { CSSProperties } from 'react'; -import { useReducer, useRef, useState } from 'react'; +import { useEffect, useReducer, useRef, useState } from 'react'; import type { ObjectPagePropTypes } from '../..'; import { Avatar, @@ -879,6 +879,26 @@ describe('ObjectPage', () => { cy.get('@sectionChangeSpy').should('not.have.been.called'); }); + it('IconTabBar mode: only mount single section', () => { + const cbSpy = cy.spy().as('cb'); + const CallBackComp = () => { + useEffect(() => { + cbSpy(); + }, []); + return null; + }; + cy.mount( + + Dummy + + + + + ); + cy.findByText('Dummy').should('be.visible'); + cy.get('@cb').should('not.been.called'); + }); + cypressPassThroughTestsFactory(ObjectPage); }); diff --git a/packages/main/src/components/ObjectPage/index.tsx b/packages/main/src/components/ObjectPage/index.tsx index 01b22d45d31..472d8939a01 100644 --- a/packages/main/src/components/ObjectPage/index.tsx +++ b/packages/main/src/components/ObjectPage/index.tsx @@ -235,7 +235,7 @@ const ObjectPage = forwardRef((props, ref) const titleInHeader = headerTitle && showTitleInHeaderContent; const [sectionSpacer, setSectionSpacer] = useState(0); const [currentTabModeSection, setCurrentTabModeSection] = useState(null); - const sections = currentTabModeSection ?? children; + const sections = mode === ObjectPageMode.IconTabBar ? currentTabModeSection : children; const deprecationNoticeDisplayed = useRef(false); useEffect(() => { @@ -356,11 +356,11 @@ const ObjectPage = forwardRef((props, ref) isProgrammaticallyScrolled.current = true; setInternalSelectedSectionId(currentId); prevSelectedSectionId.current = currentId; - const sections = objectPageRef.current?.querySelectorAll('section[data-component-name="ObjectPageSection"]'); + const sectionNodes = objectPageRef.current?.querySelectorAll('section[data-component-name="ObjectPageSection"]'); const currentIndex = safeGetChildrenArray(children).findIndex((objectPageSection) => { return isValidElement(objectPageSection) && objectPageSection.props?.id === currentId; }); - fireOnSelectedChangedEvent({}, currentIndex, currentId, sections[0]); + fireOnSelectedChangedEvent({}, currentIndex, currentId, sectionNodes[0]); } }; @@ -466,15 +466,15 @@ const ObjectPage = forwardRef((props, ref) const tabContainerContainerRef = useRef(null); useEffect(() => { const objectPage = objectPageRef.current; - const sections = objectPage.querySelectorAll('[id^="ObjectPageSection"]'); - const lastSection = sections[sections.length - 1]; + const sectionNodes = objectPage.querySelectorAll('[id^="ObjectPageSection"]'); + const lastSectionNode = sectionNodes[sectionNodes.length - 1]; const observer = new ResizeObserver(([sectionElement]) => { - const subSections = lastSection.querySelectorAll('[id^="ObjectPageSubSection"]'); + const subSections = lastSectionNode.querySelectorAll('[id^="ObjectPageSubSection"]'); const lastSubSection = subSections[subSections.length - 1]; const lastSubSectionOrSection = lastSubSection ?? sectionElement.target; - if ((currentTabModeSection && !lastSubSection) || (sections.length === 1 && !lastSubSection)) { + if ((currentTabModeSection && !lastSubSection) || (sectionNodes.length === 1 && !lastSubSection)) { setSectionSpacer(0); } else { setSectionSpacer( @@ -486,8 +486,8 @@ const ObjectPage = forwardRef((props, ref) } }); - if (objectPage && lastSection) { - observer.observe(lastSection, { box: 'border-box' }); + if (objectPage && lastSectionNode) { + observer.observe(lastSectionNode, { box: 'border-box' }); } return () => { @@ -514,11 +514,13 @@ const ObjectPage = forwardRef((props, ref) if (mode === ObjectPageMode.IconTabBar) { const sectionId = e.detail.sectionId; setInternalSelectedSectionId(sectionId); - const sections = objectPageRef.current?.querySelectorAll('section[data-component-name="ObjectPageSection"]'); + const sectionNodes = objectPageRef.current?.querySelectorAll( + 'section[data-component-name="ObjectPageSection"]' + ); const currentIndex = safeGetChildrenArray(children).findIndex((objectPageSection) => { return isValidElement(objectPageSection) && objectPageSection.props?.id === sectionId; }); - debouncedOnSectionChange(e, currentIndex, sectionId, sections[currentIndex]); + debouncedOnSectionChange(e, currentIndex, sectionId, sectionNodes[currentIndex]); } const subSectionId = e.detail.subSectionId; scrollTimeout.current = performance.now() + 200; @@ -537,7 +539,7 @@ const ObjectPage = forwardRef((props, ref) const { onScroll: _0, selectedSubSectionId: _1, ...propsWithoutOmitted } = rest; useEffect(() => { - const sections = objectPageRef.current?.querySelectorAll('section[data-component-name="ObjectPageSection"]'); + const sectionNodes = objectPageRef.current?.querySelectorAll('section[data-component-name="ObjectPageSection"]'); const objectPageHeight = objectPageRef.current?.clientHeight ?? 1000; const marginBottom = objectPageHeight - totalHeaderHeight - /*TabContainer*/ TAB_CONTAINER_HEADER_HEIGHT; const rootMargin = `-${totalHeaderHeight}px 0px -${marginBottom < 0 ? 0 : marginBottom}px 0px`; @@ -564,7 +566,7 @@ const ObjectPage = forwardRef((props, ref) } ); - sections.forEach((el) => { + sectionNodes.forEach((el) => { observer.observe(el); }); @@ -575,17 +577,17 @@ const ObjectPage = forwardRef((props, ref) // Fallback when scrolling faster than the IntersectionObserver can observe (in most cases faster than 60fps) useEffect(() => { - const sections = objectPageRef.current?.querySelectorAll('section[data-component-name="ObjectPageSection"]'); + const sectionNodes = objectPageRef.current?.querySelectorAll('section[data-component-name="ObjectPageSection"]'); if (isAfterScroll) { - let currentSection = sections[sections.length - 1]; + let currentSection = sectionNodes[sectionNodes.length - 1]; let currentIndex: number; - for (let i = 0; i <= sections.length - 1; i++) { - const section = sections[i]; + for (let i = 0; i <= sectionNodes.length - 1; i++) { + const sectionNode = sectionNodes[i]; if ( objectPageRef.current.getBoundingClientRect().top + totalHeaderHeight + TAB_CONTAINER_HEADER_HEIGHT <= - section.getBoundingClientRect().bottom + sectionNode.getBoundingClientRect().bottom ) { - currentSection = section; + currentSection = sectionNode; currentIndex = i; break; } @@ -595,7 +597,7 @@ const ObjectPage = forwardRef((props, ref) setInternalSelectedSectionId(currentSectionId); debouncedOnSectionChange( scrollEvent.current, - currentIndex ?? sections.length - 1, + currentIndex ?? sectionNodes.length - 1, currentSectionId, currentSection );