Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import '@ui5/webcomponents-fiori/dist/illustrations/UnableToLoad.js';
import SampleImage from '@sb/demoImages/Person.png';
import type { Meta, StoryObj } from '@storybook/react';
import { fn } from '@storybook/test';
import BarDesign from '@ui5/webcomponents/dist/types/BarDesign.js';
import ButtonDesign from '@ui5/webcomponents/dist/types/ButtonDesign.js';
import ValueState from '@ui5/webcomponents-base/dist/types/ValueState.js';
Expand Down Expand Up @@ -59,6 +60,7 @@ const meta = {
imageShapeCircle: true,
image: SampleImage,
style: { height: '700px', maxHeight: '90vh' },
onToggleHeaderArea: fn(),
footerArea: (
<Bar
design={BarDesign.FloatingFooter}
Expand All @@ -73,7 +75,9 @@ const meta = {
titleArea: (
<ObjectPageTitle
header={<Title level="H2">Denise Smith</Title>}
snappedHeader={<Title level="H2">Denise Smith (snapped header)</Title>}
subHeader="Senior UI Developer"
snappedSubHeader={'Senior UI Developer (snapped header)'}
actionsBar={
<Toolbar design="Transparent">
<ToolbarButton design={ButtonDesign.Emphasized} text="Primary Action" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,62 @@ describe('ObjectPageTitle', () => {
cy.findByTestId('expandedContent').should('not.exist');
});
});

[
{ snappedHeader: 'Snapped Header', header: 'Header' },
{ snappedHeader: undefined, header: 'Header' },
{ snappedHeader: undefined, header: undefined },
{ snappedHeader: 'Snapped Header', header: undefined },
].forEach(({ snappedHeader, header }) => {
const titleParts = [];
if (snappedHeader) {
titleParts.push('snappedHeader');
}
if (header) {
titleParts.push('header');
}
const title = titleParts.length ? titleParts.join(' & ') : 'no headers';

it(`renders with ${title}`, () => {
cy.mount(
<PageComponent
childrenScrollable
pageProps={{
headerArea: (
<ObjectPageHeader key="headerContent" style={{ height: '100px', background: 'lightblue' }}>
Header Section
</ObjectPageHeader>
),
style: { height: '800px' },
}}
titleProps={{
snappedHeader,
header,
}}
/>,
);

// not snapped - always show header
cy.findByText('Snapped Header').should('not.exist');
if (header) {
cy.findByText('Header').should('exist');
} else {
cy.findByText('Header').should('not.exist');
}

cy.findByTestId('page').scrollTo('bottom');

// snapped - show snapped header if defined otherwise show header
if (snappedHeader) {
cy.findByText('Snapped Header').should('exist');
cy.findByText('Header').should('not.exist');
} else if (header) {
cy.findByText('Snapped Header').should('not.exist');
cy.findByText('Header').should('exist');
} else {
cy.findByText('Snapped Header').should('not.exist');
cy.findByText('Header').should('not.exist');
}
});
});
});
12 changes: 8 additions & 4 deletions packages/main/src/components/ObjectPageTitle/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ const ObjectPageTitle = forwardRef<HTMLDivElement, ObjectPageTitlePropTypes>((pr
onToggleHeaderContentVisibility,
expandedContent,
snappedContent,
snappedHeader,
snappedSubHeader,
_snappedAvatar,
...rest
} = props as InternalProps;
Expand All @@ -41,6 +43,8 @@ const ObjectPageTitle = forwardRef<HTMLDivElement, ObjectPageTitlePropTypes>((pr
);
const containerClasses = clsx(classNames.container, isPhone && classNames.phone, className);
const toolbarContainerRef = useRef<HTMLDivElement>(null);
const _header = !props?.['data-header-content-visible'] && snappedHeader ? snappedHeader : header;
const _subHeader = !props?.['data-header-content-visible'] && snappedSubHeader ? snappedSubHeader : subHeader;

useEffect(() => {
isMounted.current = true;
Expand Down Expand Up @@ -157,9 +161,9 @@ const ObjectPageTitle = forwardRef<HTMLDivElement, ObjectPageTitlePropTypes>((pr
data-component-name="ObjectPageTitleMiddleSection"
>
<FlexBox className={classNames.titleMainSection} onClick={onHeaderClick}>
{header && (
{_header && (
<div className={classNames.title} data-component-name="ObjectPageTitleHeader">
{header}
{_header}
</div>
)}
{children && (
Expand All @@ -182,13 +186,13 @@ const ObjectPageTitle = forwardRef<HTMLDivElement, ObjectPageTitlePropTypes>((pr
</div>
)}
</FlexBox>
{subHeader && (
{_subHeader && (
<FlexBox id="sub">
<div
className={clsx(classNames.subTitle, classNames.subTitleBottom)}
data-component-name="ObjectPageTitleSubHeader"
>
{subHeader}
{_subHeader}
</div>
</FlexBox>
)}
Expand Down
26 changes: 22 additions & 4 deletions packages/main/src/components/ObjectPageTitle/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,33 @@ export interface ObjectPageTitlePropTypes extends CommonProps {
children?: ReactNode | ReactNode[];

/**
* The `header` is positioned in the `ObjectPageTitle` left area.
* Use this prop to display a `Title` (or any other component that serves as a heading).
* The `header` is displayed in the left area of the `ObjectPageTitle`.
* Use this prop to render a `Title` or any other component that serves as a heading.
*
* __Note:__ If the header is snapped (collapsed), the `snappedHeader` prop is used instead (if defined).
*/
header?: ReactNode;
/**
* The `subHeader` is positioned in the `ObjectPageTitle` left area below the `header`.
* Use this aggregation to display a component like `Label` or any other component that serves as sub header.
* The `snappedHeader` is displayed in the left area of the `ObjectPageTitle` when the header is snapped (collapsed).
* Use this prop to render a `Title` or any other component that serves as a heading in the snapped view.
*
* @since 2.12.0
*/
snappedHeader?: ReactNode;
/**
* The `subHeader` is displayed in the left area of the `ObjectPageTitle`, below the `header`.
* Use this prop to render a `Label` or any other component that serves as a sub-header.
*
* __Note:__ If the header is snapped (collapsed), the `snappedSubHeader` prop is used instead (if defined).
*/
subHeader?: ReactNode;
/**
* The `snappedSubHeader` is displayed in the left area of the `ObjectPageTitle` when the header is snapped (collapsed).
* Use this prop to render a `Label` or any other component that serves as a sub-header in the snapped view.
*
* @since 2.12.0
*/
snappedSubHeader?: ReactNode;
/**
* Defines navigation-actions bar of the `ObjectPageTitle`.
*
Expand Down
Loading