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
Expand Up @@ -1030,6 +1030,7 @@ export interface AnalyticalTablePropTypes extends Omit<CommonProps, 'title'> {
nativeDetail: number;
}>,
) => void;
//todo: add cursor pointer when this prop is active in next major version update.
/**
* Fired when a row is clicked
*/
Expand Down
175 changes: 91 additions & 84 deletions packages/main/src/components/ObjectPage/ObjectPage.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -662,29 +662,52 @@ describe('ObjectPage', () => {
cy.findByTestId('footer').should('be.visible');
});

it('single section - Default mode', () => {
document.body.style.margin = '0px';
const TestComp = ({
mode,
height,
withFooter,
}: {
height: CSSProperties['height'];
withFooter?: boolean;
mode: ObjectPageMode;
}) => {
const ref = useRef(null);
const [showCurrentHeights, setShowCurrentHeights] = useState({ offset: null, scroll: null });
return (
<ObjectPage
style={{ height: '100vh' }}
titleArea={DPTitle}
headerArea={DPContent}
data-testid="op"
ref={ref}
footerArea={withFooter && Footer}
mode={mode}
>
const TestSingleSectionComp = ({
mode,
height,
withFooter,
withSubSections,
}: {
height: CSSProperties['height'];
withFooter?: boolean;
mode: ObjectPageMode;
withSubSections?: boolean;
}) => {
const ref = useRef(null);
const [showCurrentHeights, setShowCurrentHeights] = useState({ offset: null, scroll: null });
return (
<ObjectPage
style={{ height: '100vh' }}
titleArea={DPTitle}
headerArea={DPContent}
data-testid="op"
ref={ref}
footerArea={withFooter && Footer}
mode={mode}
>
{withSubSections ? (
<ObjectPageSection key="0" titleText="Goals" id="goals" aria-label="Goals">
<ObjectPageSubSection id="0.0" titleText="0.0">
<div data-testid="section 1" style={{ height, width: '100%', background: 'lightblue' }}>
<Button
onClick={() => {
setShowCurrentHeights({
// rounding offset/scroll-height differs from browser to browser and maybe even from headless tests
offset: Math.floor(ref.current?.offsetHeight / 10) * 10,
scroll: Math.floor(ref.current?.scrollHeight / 10) * 10,
});
}}
>
Update Heights
</Button>
{JSON.stringify(showCurrentHeights)}
</div>
</ObjectPageSubSection>
<ObjectPageSubSection id="0.1" titleText="0.0">
<div data-testid="section 2" style={{ height: '400px', width: '100%', background: 'lightgreen' }}></div>
</ObjectPageSubSection>
</ObjectPageSection>
) : (
<ObjectPageSection key="0" titleText="Goals" id="goals" aria-label="Goals">
<div data-testid="section 1" style={{ height, width: '100%', background: 'lightblue' }}>
<Button
Expand All @@ -701,26 +724,35 @@ describe('ObjectPage', () => {
{JSON.stringify(showCurrentHeights)}
</div>
</ObjectPageSection>
</ObjectPage>
);
};
cy.mount(<TestComp height="2000px" mode={ObjectPageMode.Default} />);
)}
</ObjectPage>
);
};

it('single section - Default mode', () => {
document.body.style.margin = '0px';

cy.mount(<TestSingleSectionComp height="2000px" mode={ObjectPageMode.Default} />);

cy.get('[data-component-name="ObjectPageTabContainerPlaceholder"]').should('exist');
cy.get('[data-component-name="ObjectPageTabContainer"]').should('not.exist');

cy.findByText('Update Heights').click();
cy.findByText('{"offset":1080,"scroll":2330}').should('exist');
cy.findByText('{"offset":1080,"scroll":2280}').should('exist');

cy.findByTestId('op').scrollTo('bottom');
cy.findByText('Update Heights').click({ force: true });
cy.findByText('{"offset":1080,"scroll":2330}').should('exist');
cy.findByText('{"offset":1080,"scroll":2280}').should('exist');

cy.mount(<TestComp height="2000px" withFooter mode={ObjectPageMode.Default} />);
cy.mount(<TestSingleSectionComp height="2000px" withFooter mode={ObjectPageMode.Default} />);
cy.findByText('Update Heights').click();
cy.findByText('{"offset":1080,"scroll":2370}').should('exist');
cy.findByText('{"offset":1080,"scroll":2320}').should('exist');

cy.findByTestId('op').scrollTo('bottom');
cy.findByText('Update Heights').click({ force: true });
cy.findByText('{"offset":1080,"scroll":2370}').should('exist');
cy.findByText('{"offset":1080,"scroll":2320}').should('exist');

cy.mount(<TestComp height="400px" mode={ObjectPageMode.Default} />);
cy.mount(<TestSingleSectionComp height="400px" mode={ObjectPageMode.Default} />);
cy.findByText('Update Heights').click();
cy.findByText('{"offset":1080,"scroll":1080}').should('exist');

Expand All @@ -732,7 +764,7 @@ describe('ObjectPage', () => {
cy.findByText('Update Heights').click({ force: true });
cy.findByText('{"offset":1080,"scroll":1080}').should('exist');

cy.mount(<TestComp height="400px" withFooter mode={ObjectPageMode.Default} />);
cy.mount(<TestSingleSectionComp height="400px" withFooter mode={ObjectPageMode.Default} />);
cy.findByText('Update Heights').click();
cy.findByText('{"offset":1080,"scroll":1080}').should('exist');

Expand All @@ -744,7 +776,7 @@ describe('ObjectPage', () => {
cy.findByText('Update Heights').click({ force: true });
cy.findByText('{"offset":1080,"scroll":1080}').should('exist');

cy.mount(<TestComp height="925px" mode={ObjectPageMode.Default} />);
cy.mount(<TestSingleSectionComp height="925px" mode={ObjectPageMode.Default} />);
cy.findByText('https://github.com/UI5/webcomponents-react').should('be.visible');

cy.wait(50);
Expand All @@ -757,67 +789,36 @@ describe('ObjectPage', () => {

cy.get('[data-component-name="ObjectPageAnchorBarExpandBtn"]').click();
cy.findByText('https://github.com/UI5/webcomponents-react').should('not.be.visible');

cy.log('with subsections');
cy.mount(<TestSingleSectionComp height="2000px" withSubSections mode={ObjectPageMode.Default} />);
cy.get('[data-component-name="ObjectPageTabContainerPlaceholder"]').should('exist');
cy.get('[data-component-name="ObjectPageTabContainer"]').should('not.exist');
});

it('single section - Tab mode', () => {
document.body.style.margin = '0px';
const TestComp = ({
mode,
height,
withFooter,
}: {
height: CSSProperties['height'];
withFooter?: boolean;
mode: ObjectPageMode;
}) => {
const ref = useRef(null);
const [showCurrentHeights, setShowCurrentHeights] = useState({ offset: null, scroll: null });
return (
<ObjectPage
style={{ height: '100vh' }}
titleArea={DPTitle}
headerArea={DPContent}
data-testid="op"
ref={ref}
footerArea={withFooter && Footer}
mode={mode}
>
<ObjectPageSection key="0" titleText="Goals" id="goals" aria-label="Goals">
<div data-testid="section 1" style={{ height, width: '100%', background: 'lightblue' }}>
<Button
onClick={() => {
setShowCurrentHeights({
// rounding offset/scroll-height differs from browser to browser and maybe even from headless tests
offset: Math.floor(ref.current?.offsetHeight / 10) * 10,
scroll: Math.floor(ref.current?.scrollHeight / 10) * 10,
});
}}
>
Update Heights
</Button>
{JSON.stringify(showCurrentHeights)}
</div>
</ObjectPageSection>
</ObjectPage>
);
};
cy.mount(<TestComp height="2000px" mode={ObjectPageMode.IconTabBar} />);
cy.mount(<TestSingleSectionComp height="2000px" mode={ObjectPageMode.IconTabBar} />);

cy.get('[data-component-name="ObjectPageTabContainerPlaceholder"]').should('exist');
cy.get('[data-component-name="ObjectPageTabContainer"]').should('not.exist');

cy.findByText('Update Heights').click();
cy.findByText('{"offset":1080,"scroll":2290}').should('exist');
cy.findByText('{"offset":1080,"scroll":2240}').should('exist');

cy.findByTestId('op').scrollTo('bottom');
cy.findByText('Update Heights').click({ force: true });
cy.findByText('{"offset":1080,"scroll":2290}').should('exist');
cy.findByText('{"offset":1080,"scroll":2240}').should('exist');

cy.mount(<TestComp height="2000px" withFooter mode={ObjectPageMode.IconTabBar} />);
cy.mount(<TestSingleSectionComp height="2000px" withFooter mode={ObjectPageMode.IconTabBar} />);
cy.findByText('Update Heights').click();
cy.findByText('{"offset":1080,"scroll":2350}').should('exist');
cy.findByText('{"offset":1080,"scroll":2300}').should('exist');

cy.findByTestId('op').scrollTo('bottom');
cy.findByText('Update Heights').click({ force: true });
cy.findByText('{"offset":1080,"scroll":2350}').should('exist');
cy.findByText('{"offset":1080,"scroll":2300}').should('exist');

cy.mount(<TestComp height="400px" mode={ObjectPageMode.IconTabBar} />);
cy.mount(<TestSingleSectionComp height="400px" mode={ObjectPageMode.IconTabBar} />);
cy.findByText('Update Heights').click();
cy.findByText('{"offset":1080,"scroll":1080}').should('exist');

Expand All @@ -829,7 +830,7 @@ describe('ObjectPage', () => {
cy.findByText('Update Heights').click({ force: true });
cy.findByText('{"offset":1080,"scroll":1080}').should('exist');

cy.mount(<TestComp height="400px" withFooter mode={ObjectPageMode.IconTabBar} />);
cy.mount(<TestSingleSectionComp height="400px" withFooter mode={ObjectPageMode.IconTabBar} />);
cy.findByText('Update Heights').click();
cy.findByText('{"offset":1080,"scroll":1080}').should('exist');

Expand All @@ -841,7 +842,7 @@ describe('ObjectPage', () => {
cy.findByText('Update Heights').click({ force: true });
cy.findByText('{"offset":1080,"scroll":1080}').should('exist');

cy.mount(<TestComp height="925px" mode={ObjectPageMode.IconTabBar} />);
cy.mount(<TestSingleSectionComp height="925px" mode={ObjectPageMode.IconTabBar} />);
cy.findByText('https://github.com/UI5/webcomponents-react').should('be.visible');

cy.wait(50);
Expand All @@ -854,7 +855,13 @@ describe('ObjectPage', () => {

cy.get('[data-component-name="ObjectPageAnchorBarExpandBtn"]').click();
cy.findByText('https://github.com/UI5/webcomponents-react').should('not.be.visible');

cy.log('with subsections');
cy.mount(<TestSingleSectionComp height="2000px" withSubSections mode={ObjectPageMode.Default} />);
cy.get('[data-component-name="ObjectPageTabContainerPlaceholder"]').should('exist');
cy.get('[data-component-name="ObjectPageTabContainer"]').should('not.exist');
});

[ObjectPageMode.Default, ObjectPageMode.IconTabBar].forEach((mode) => {
it(`ObjectPageSection/SubSection: Custom header & hideTitleText (mode: ${mode})`, () => {
document.body.style.margin = '0px';
Expand Down
6 changes: 6 additions & 0 deletions packages/main/src/components/ObjectPage/ObjectPage.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ To render a single section in fullscreen mode, set its height to `100%`.
</ObjectPageSection>
```

## ObjectPage with single section

When only a single section is available, the tabbar is hidden.

<Canvas of={ComponentStories.SingleSection} />

## Opening popover components by pressing an action

Please see the [Docs](?path=/docs/layouts-floorplans-toolbar--docs#open-popovers-with-toolbarbutton) of the `Toolbar` component.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@
background: var(--sapObjectHeader_Background);
}

.tabContainerPlaceholder {
composes: tabContainer;
box-shadow: var(--sapContent_HeaderShadow);
height: 1px;
flex-shrink: 0;
}

.tabContainerComponent {
&::part(content) {
display: none;
Expand Down
88 changes: 87 additions & 1 deletion packages/main/src/components/ObjectPage/ObjectPage.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ const meta = {
},
args: {
mode: ObjectPageMode.Default,
selectedSectionId: 'goals',
imageShapeCircle: true,
image: SampleImage,
style: { height: '700px', maxHeight: '90vh' },
Expand Down Expand Up @@ -451,6 +450,93 @@ export const FullScreenSingleSection: Story = {
},
};

export const SingleSection: Story = {
name: 'with single section',
render(args) {
return (
<ObjectPage {...args}>
<ObjectPageSection titleText="Employment" id="employment" aria-label="Employment">
<ObjectPageSubSection
titleText="Job Information"
id="employment-job-information"
aria-label="Job Information"
>
<Form>
<FormItem labelContent={<Label showColon>Job Classification</Label>}>
<FlexBox direction={FlexBoxDirection.Column}>
<Text>Senior UI Developer</Text>
<Label>(UIDEV-SR)</Label>
</FlexBox>
</FormItem>
<FormItem labelContent={<Label showColon>Job Title</Label>}>
<Text>Developer</Text>
</FormItem>
<FormItem labelContent={<Label showColon>Employee Class</Label>}>
<Text>Employee</Text>
</FormItem>
<FormItem labelContent={<Label showColon>Manager</Label>}>
<FlexBox direction={FlexBoxDirection.Column}>
<Text>Dan Smith</Text>
<Label>Development Manager</Label>
</FlexBox>
</FormItem>
<FormItem labelContent={<Label showColon>Pay Grade</Label>}>
<Text>Salary Grade 18 (GR-14)</Text>
</FormItem>
<FormItem labelContent={<Label showColon>FTE</Label>}>
<Text>1</Text>
</FormItem>
</Form>
</ObjectPageSubSection>
<ObjectPageSubSection
titleText="Employee Details"
id="employment-employee-details"
aria-label="Employee Details"
>
<Form>
<FormItem labelContent={<Label showColon>Start Date</Label>}>
<Text>Jan 01, 2018</Text>
</FormItem>
<FormItem labelContent={<Label showColon>End Date</Label>}>
<Text>Dec 31, 9999</Text>
</FormItem>
<FormItem labelContent={<Label showColon>Payroll Start Date</Label>}>
<Text>Jan 01, 2018</Text>
</FormItem>
<FormItem labelContent={<Label showColon>Benefits Start Date</Label>}>
<Text>Jul 01, 2018</Text>
</FormItem>
<FormItem labelContent={<Label showColon>Company Car Eligibility</Label>}>
<Text>Jan 01, 2021</Text>
</FormItem>
<FormItem labelContent={<Label showColon>Equity Start Date</Label>}>
<Text>Jul 01, 2018</Text>
</FormItem>
</Form>
</ObjectPageSubSection>
<ObjectPageSubSection
titleText="Job Relationship"
id="employment-job-relationship"
aria-label="Job Relationship"
>
<Form>
<FormItem labelContent={<Label showColon>Manager</Label>}>
<Text>John Doe</Text>
</FormItem>
<FormItem labelContent={<Label showColon>Scrum Master</Label>}>
<Text>Michael Adams</Text>
</FormItem>
<FormItem labelContent={<Label showColon>Product Owner</Label>}>
<Text>John Miller</Text>
</FormItem>
</Form>
</ObjectPageSubSection>
</ObjectPageSection>
</ObjectPage>
);
},
};

export const LegacyToolbarSupport: Story = {
render(args) {
const objectPageRef = useRef<ObjectPageDomRef>(null);
Expand Down
Loading
Loading