diff --git a/packages/main/src/components/ObjectPage/ObjectPage.cy.tsx b/packages/main/src/components/ObjectPage/ObjectPage.cy.tsx index d428e21cf71..4f2fe78a8d2 100644 --- a/packages/main/src/components/ObjectPage/ObjectPage.cy.tsx +++ b/packages/main/src/components/ObjectPage/ObjectPage.cy.tsx @@ -71,6 +71,28 @@ describe('ObjectPage', () => { cy.findByText('ObjectPageHeader').should('be.visible'); cy.get('@toggleSpy').should('have.been.calledWith', true); cy.get('@toggleSpy').should('have.callCount', 4); + + cy.mount( + <ObjectPage + headerTitle={<ObjectPageTitle header="Heading" subHeader="SubHeading" />} + headerContent={<ObjectPageHeader>ObjectPageHeader</ObjectPageHeader>} + onToggleHeaderContent={toggle} + hidePinButton + preserveHeaderStateOnClick + > + <ObjectPageSection id="section" titleText="Section"> + Content + </ObjectPageSection> + </ObjectPage> + ); + + cy.findByText('Heading').click(); + cy.findByText('ObjectPageHeader').should('be.visible'); + cy.get('@toggleSpy').should('have.callCount', 4); + + cy.get('[data-component-name="ObjectPageTitle"]').click(); + cy.findByText('ObjectPageHeader').should('be.visible'); + cy.get('@toggleSpy').should('have.callCount', 4); }); it('pin header', () => { diff --git a/packages/main/src/components/ObjectPage/index.tsx b/packages/main/src/components/ObjectPage/index.tsx index 2d76f782d25..5bdf6e5f03e 100644 --- a/packages/main/src/components/ObjectPage/index.tsx +++ b/packages/main/src/components/ObjectPage/index.tsx @@ -132,6 +132,12 @@ export interface ObjectPagePropTypes extends Omit<CommonProps, 'placeholder'> { * Defines if the pin button for the `headerContent` is hidden. */ hidePinButton?: boolean; + /** + * Determines whether the user can switch between the expanded/collapsed states of the `ObjectPageHeader` by clicking on the `ObjectPageTitle`. + * + * __Note:__ Per default the header is toggleable. + */ + preserveHeaderStateOnClick?: boolean; /** * Defines internally used accessibility properties/attributes. */ @@ -192,6 +198,7 @@ const ObjectPage = forwardRef<HTMLDivElement, ObjectPagePropTypes>((props, ref) headerPinned: headerPinnedProp, headerContent, hidePinButton, + preserveHeaderStateOnClick, accessibilityAttributes, placeholder, onSelectedSectionChange, @@ -598,13 +605,11 @@ const ObjectPage = forwardRef<HTMLDivElement, ObjectPagePropTypes>((props, ref) } }, [isAfterScroll]); - const onTitleClick = useCallback( - (e) => { - e.stopPropagation(); + const onTitleClick = (e) => { + e.stopPropagation(); + if (!preserveHeaderStateOnClick) onToggleHeaderContentVisibility(enrichEventWithDetails(e, { visible: headerCollapsed })); - }, - [onToggleHeaderContentVisibility, headerCollapsed] - ); + }; const snappedHeaderInObjPage = headerTitle && headerTitle.props.snappedContent && headerCollapsed === true && !!image; @@ -743,7 +748,7 @@ const ObjectPage = forwardRef<HTMLDivElement, ObjectPagePropTypes>((props, ref) data-component-name="ObjectPageTopHeader" ref={topHeaderRef} role={accessibilityAttributes?.objectPageTopHeader?.role} - data-not-clickable={false} + data-not-clickable={!!preserveHeaderStateOnClick} aria-roledescription={accessibilityAttributes?.objectPageTopHeader?.ariaRoledescription ?? 'Object Page header'} className={classNames.header} onClick={onTitleClick} @@ -760,7 +765,7 @@ const ObjectPage = forwardRef<HTMLDivElement, ObjectPagePropTypes>((props, ref) cloneElement(headerTitle as ReactElement<ObjectPageTitlePropsWithDataAttributes>, { className: clsx(headerTitle?.props?.className), onToggleHeaderContentVisibility: onTitleClick, - 'data-not-clickable': false, + 'data-not-clickable': !!preserveHeaderStateOnClick, 'data-header-content-visible': headerContent && headerCollapsed !== true, 'data-is-snapped-rendered-outside': snappedHeaderInObjPage })}