diff --git a/packages/main/src/components/ObjectPage/ObjectPage.cy.tsx b/packages/main/src/components/ObjectPage/ObjectPage.cy.tsx index ffea406fc7d..15b011c7276 100644 --- a/packages/main/src/components/ObjectPage/ObjectPage.cy.tsx +++ b/packages/main/src/components/ObjectPage/ObjectPage.cy.tsx @@ -1358,6 +1358,70 @@ describe('ObjectPage', () => { }); }); + it('accessibilityAttributes', () => { + cy.mount( + + {OPContent} + , + ); + + cy.get('header').should('not.have.attr', 'role'); + cy.get('header').should('have.attr', 'aria-roledescription', 'Object Page header'); + cy.get('[data-component-name="ObjectPageAnchorBarExpandBtn"]').should(($el) => { + expect($el[0].accessibilityAttributes.expanded).to.equal(true); + }); + cy.get('[data-component-name="ObjectPageAnchorBarExpandBtn"]').should( + 'have.attr', + 'accessible-name', + 'Collapse Header', + ); + cy.get('section[data-component-name="ObjectPageAnchorBar"]').should('not.have.attr', 'role'); + cy.get('footer').should('not.have.attr', 'role'); + + const accessibilityAttributes = { + objectPageTopHeader: { + role: 'banner', + ariaRoledescription: 'ariaRoledescription', + }, + objectPageAnchorBar: { + expandButton: { + expanded: undefined, + accessibleName: '', + }, + role: 'not-a-real-role', + }, + objectPageFooterArea: { + role: 'contentinfo', + }, + }; + + cy.mount( + + {OPContent} + , + ); + + cy.get('header').should('have.attr', 'role', 'banner'); + cy.get('header').should('have.attr', 'aria-roledescription', 'ariaRoledescription'); + cy.get('[data-component-name="ObjectPageAnchorBarExpandBtn"]').should(($el) => { + const attrs = $el[0].accessibilityAttributes; + + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + expect(attrs).to.exist; + expect(attrs).to.haveOwnProperty('expanded'); + expect(attrs.expanded).to.equal(undefined); + }); + cy.get('[data-component-name="ObjectPageAnchorBarExpandBtn"]').should('have.attr', 'accessible-name', ''); + cy.get('section[data-component-name="ObjectPageAnchorBar"]').should('have.attr', 'role', 'not-a-real-role'); + cy.get('footer').should('have.attr', 'role', 'contentinfo'); + }); + cypressPassThroughTestsFactory(ObjectPage); }); diff --git a/packages/main/src/components/ObjectPage/index.tsx b/packages/main/src/components/ObjectPage/index.tsx index 5e70abf034e..2c0aaf32e97 100644 --- a/packages/main/src/components/ObjectPage/index.tsx +++ b/packages/main/src/components/ObjectPage/index.tsx @@ -650,7 +650,7 @@ const ObjectPage = forwardRef((props, ref headerContentVisible={headerArea && headerCollapsed !== true} hidePinButton={!!hidePinButton} headerPinned={headerPinned} - accessibilityAttributes={accessibilityAttributes} + accessibilityAttributes={accessibilityAttributes?.objectPageAnchorBar} onToggleHeaderContentVisibility={onToggleHeaderContentVisibility} setHeaderPinned={setHeaderPinned} onHoverToggleButton={onHoverToggleButton} diff --git a/packages/main/src/components/ObjectPage/types/index.ts b/packages/main/src/components/ObjectPage/types/index.ts index 05e0075f9c8..79c459e689d 100644 --- a/packages/main/src/components/ObjectPage/types/index.ts +++ b/packages/main/src/components/ObjectPage/types/index.ts @@ -3,6 +3,7 @@ import type { CommonProps, Ui5CustomEvent } from '@ui5/webcomponents-react-base' import type { ReactElement, ReactNode } from 'react'; import type { ObjectPageMode } from '../../../enums/ObjectPageMode.js'; import type { AvatarPropTypes } from '../../../webComponents/Avatar/index.js'; +import type { ButtonPropTypes } from '../../../webComponents/Button/index.js'; import type { TabContainerDomRef } from '../../../webComponents/TabContainer/index.js'; import type { ObjectPageHeaderPropTypes } from '../../ObjectPageHeader/index.js'; import type { ObjectPageSectionPropTypes } from '../../ObjectPageSection/index.js'; @@ -106,7 +107,12 @@ export interface ObjectPagePropTypes extends Omit { role?: string; ariaRoledescription?: string; }; + //todo: rename in next major version to better reflect what part of the ObjectPage it describes objectPageAnchorBar?: { + expandButton?: { + expanded?: ButtonPropTypes['accessibilityAttributes']['expanded'] | undefined; + accessibleName?: ButtonPropTypes['accessibleName']; + }; role?: string; }; objectPageFooterArea?: { diff --git a/packages/main/src/components/ObjectPageAnchorBar/index.tsx b/packages/main/src/components/ObjectPageAnchorBar/index.tsx index 1595b3f314b..3234ab93a62 100644 --- a/packages/main/src/components/ObjectPageAnchorBar/index.tsx +++ b/packages/main/src/components/ObjectPageAnchorBar/index.tsx @@ -15,6 +15,7 @@ import type { ButtonDomRef } from '../../webComponents/Button/index.js'; import { Button } from '../../webComponents/Button/index.js'; import type { ToggleButtonDomRef, ToggleButtonPropTypes } from '../../webComponents/ToggleButton/index.js'; import { ToggleButton } from '../../webComponents/ToggleButton/index.js'; +import type { ObjectPagePropTypes } from '../ObjectPage/types/index.js'; import { classNames, styleData } from './ObjectPageAnchorBar.module.css.js'; const _buttonBaseMinWidth = `${cssVarVersionInfoPrefix}button_base_min_width`; @@ -53,11 +54,7 @@ interface ObjectPageAnchorBarPropTypes extends CommonProps { /** * Defines internally used accessibility properties/attributes. */ - accessibilityAttributes?: { - objectPageAnchorBar?: { - role?: string; - }; - }; + accessibilityAttributes?: ObjectPagePropTypes['accessibilityAttributes']['objectPageAnchorBar']; /** * Fired when the `headerContent` changes its pinned state. */ @@ -114,14 +111,18 @@ const ObjectPageAnchorBar = forwardRef { if (showHideHeaderBtn) { + const expanded = + accessibilityAttributes?.expandButton && Object.hasOwn(accessibilityAttributes.expandButton, 'expanded') + ? accessibilityAttributes.expandButton.expanded + : !!headerContentVisible; showHideHeaderBtn.accessibilityAttributes = { - expanded: !!headerContentVisible, + expanded, hasPopup: undefined, controls: undefined, }; } }); - }, [!!headerContentVisible]); + }, [accessibilityAttributes?.expandButton?.expanded, !!headerContentVisible]); const onToggleHeaderButtonClick = (e) => { onToggleHeaderContentVisibility(enrichEventWithDetails(e, { visible: !headerContentVisible })); @@ -131,7 +132,7 @@ const ObjectPageAnchorBar = forwardRef @@ -149,7 +150,10 @@ const ObjectPageAnchorBar = forwardRef {shouldRenderHeaderPinnableButton && ( diff --git a/tsconfig.spec.json b/tsconfig.spec.json index 192cf622dde..d34ee5da25b 100644 --- a/tsconfig.spec.json +++ b/tsconfig.spec.json @@ -2,7 +2,7 @@ "compilerOptions": { "target": "ES2021", "lib": ["es2022", "dom"], - "types": ["cypress", "node", "@testing-library/cypress", "cypress-real-events"], + "types": ["cypress", "node", "@testing-library/cypress", "cypress-real-events", "chai"], "moduleResolution": "Node", "jsx": "react-jsx", "composite": true