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
6 changes: 3 additions & 3 deletions packages/main/__karma_snapshots__/Page.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@
#### `Basic Page`

```
<div class="Page-pageContainer--- Page-pageWithHeader--- Page-pageWithFooter--- Page-backgroundStandard---"><header class="Page-pageHeader--- Page-baseBar---"><div data-bar-part="Root" class="Bar-bar---"><div data-bar-part="Left" class="Bar-left---"><ui5-button icon="navigation-left-arrow" design="Transparent" class></ui5-button></div><div data-bar-part="Center" class="Bar-center---"><div class="Bar-inner---"><ui5-title level="H5" class>Page Demo</ui5-title></div></div><div data-bar-part="Right" class="Bar-right---"></div></div></header><section class="Page-contentSection---">Page Content</section><footer class="Page-pageFooter--- Page-baseBar---"></footer></div>
<div class="Page--pageContainer--- Page--pageWithHeader--- Page--pageWithFooter--- Page--backgroundStandard---"><header class="Page--pageHeader--- Page--baseBar---"><div data-bar-part="Root" class="Bar-bar---"><div data-bar-part="Left" class="Bar-left---"><ui5-button icon="navigation-left-arrow" design="Transparent" class></ui5-button></div><div data-bar-part="Center" class="Bar-center---"><div class="Bar-inner---"><ui5-title level="H5" class>Page Demo</ui5-title></div></div><div data-bar-part="Right" class="Bar-right---"></div></div></header><section class="Page--contentSection---">Page Content</section><footer class="Page--pageFooter--- Page--baseBar---"></footer></div>
```

#### `Basic Page w/o back button`

```
<div class="Page-pageContainer--- Page-pageWithHeader--- Page-pageWithFooter--- Page-backgroundStandard---"><header class="Page-pageHeader--- Page-baseBar---"><div data-bar-part="Root" class="Bar-bar---"><div data-bar-part="Left" class="Bar-left---"></div><div data-bar-part="Center" class="Bar-center---"><div class="Bar-inner---"><ui5-title level="H5" class>Page Demo</ui5-title></div></div><div data-bar-part="Right" class="Bar-right---"></div></div></header><section class="Page-contentSection---">Page Content</section><footer class="Page-pageFooter--- Page-baseBar---"></footer></div>
<div class="Page--pageContainer--- Page--pageWithHeader--- Page--pageWithFooter--- Page--backgroundStandard---"><header class="Page--pageHeader--- Page--baseBar---"><div data-bar-part="Root" class="Bar-bar---"><div data-bar-part="Left" class="Bar-left---"></div><div data-bar-part="Center" class="Bar-center---"><div class="Bar-inner---"><ui5-title level="H5" class>Page Demo</ui5-title></div></div><div data-bar-part="Right" class="Bar-right---"></div></div></header><section class="Page--contentSection---">Page Content</section><footer class="Page--pageFooter--- Page--baseBar---"></footer></div>
```

#### `Without footer and Header`

```
<section class="Page-contentSection---">Page Content</section>
<section class="Page--contentSection---">Page Content</section>
```

6 changes: 4 additions & 2 deletions packages/main/src/components/Page/demo.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { boolean, select } from '@storybook/addon-knobs';
import { boolean, select, text } from '@storybook/addon-knobs';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import React from 'react';
import { Bar } from '../../lib/Bar';
import { Button } from '../../lib/Button';
Expand All @@ -10,12 +11,13 @@ import { PageBackgroundDesign } from '../../lib/PageBackgroundDesign';
const renderPage = () => (
<div style={{ height: '400px', width: '100%' }}>
<Page
title="Page Demo"
title={text('title', 'Page Demo')}
showFooter={boolean('showFooter', true)}
showHeader={boolean('showHeader', true)}
showBackButton={boolean('showBackButton', true)}
backgroundDesign={select('backgroundDesign', PageBackgroundDesign, PageBackgroundDesign.Standard)}
renderCustomFooter={() => <Bar renderContentRight={() => <Button>Button</Button>} />}
onNavButtonPress={action('onNavButtonPress')}
>
<Label>Page Content</Label>
</Page>
Expand Down
172 changes: 89 additions & 83 deletions packages/main/src/components/Page/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Event, StyleClassHelper, withStyles } from '@ui5/webcomponents-react-base';
import React, { Component, ReactElement, ReactNode } from 'react';
import { ClassProps } from '../../interfaces/ClassProps';
import { Event, StyleClassHelper } from '@ui5/webcomponents-react-base';
import React, { forwardRef, ReactElement, ReactNode, Ref, useCallback, useMemo } from 'react';
import { createUseStyles } from 'react-jss';
import { CommonProps } from '../../interfaces/CommonProps';
import { JSSTheme } from '../../interfaces/JSSTheme';
import { Bar } from '../../lib/Bar';
import { Button } from '../../lib/Button';
import { ButtonDesign } from '../../lib/ButtonDesign';
Expand All @@ -23,89 +24,94 @@ export interface PagePropTypes extends CommonProps {
children: ReactElement<any> | Array<ReactElement<any>> | ReactNode;
}

interface PagePropsInternal extends PagePropTypes, ClassProps {}

@withStyles(styles)
export class Page extends Component<PagePropTypes> {
static defaultProps = {
showHeader: true,
showFooter: false,
showBackButton: true,
renderCustomHeader: null,
renderCustomFooter: null,
title: '',
backgroundDesign: PageBackgroundDesign.Standard
};

private handleNavBackButtonPress = (e) => {
this.props.onNavButtonPress(Event.of(this, e.getOriginalEvent()));
};

private renderBackButton = () => {
return (
<Button icon="navigation-left-arrow" design={ButtonDesign.Transparent} onClick={this.handleNavBackButtonPress} />
);
};

private renderTitle = () => <Title level={TitleLevel.H5}>{this.props.title}</Title>;

private renderHeader = () => {
const { showBackButton } = this.props;
return (
<Bar
renderContentLeft={showBackButton ? this.renderBackButton : () => null}
renderContentMiddle={this.renderTitle}
/>
);
};

render() {
const {
children,
showFooter,
showHeader,
classes,
className,
style,
renderCustomHeader,
renderCustomFooter,
backgroundDesign,
tooltip,
innerRef,
slot
} = this.props as PagePropsInternal;

const pageContainer = StyleClassHelper.of(classes.pageContainer);
const headerClasses = StyleClassHelper.of(classes.pageHeader, classes.baseBar);
const footerClasses = StyleClassHelper.of(classes.pageFooter, classes.baseBar);

if (showHeader) {
pageContainer.put(classes.pageWithHeader);
}
const useStyles = createUseStyles<JSSTheme, keyof ReturnType<typeof styles>>(styles, {
name: 'Page'
});

const Page = forwardRef((props: PagePropTypes, ref: Ref<HTMLDivElement>) => {
const {
children,
showFooter,
showHeader,
showBackButton,
className,
style,
renderCustomHeader,
renderCustomFooter,
backgroundDesign,
tooltip,
slot,
onNavButtonPress,
title
} = props;

const classes = useStyles();

if (showFooter) {
pageContainer.put(classes.pageWithFooter);
const handleNavBackButtonPress = useCallback(
(e) => {
if (typeof onNavButtonPress === 'function') {
onNavButtonPress(Event.of(null, e.getOriginalEvent()));
}
},
[onNavButtonPress]
);

const renderBackButton = useCallback(() => {
if (showBackButton) {
return (
<Button icon="navigation-left-arrow" design={ButtonDesign.Transparent} onClick={handleNavBackButtonPress} />
);
}
return null;
}, [showBackButton]);

const renderTitle = useCallback(() => <Title level={TitleLevel.H5}>{title}</Title>, [title]);

if (className) {
pageContainer.put(className);
const header = useMemo(() => {
if (renderCustomHeader) {
return renderCustomHeader();
}

pageContainer.put(classes[`background${backgroundDesign}`]);

return (
<div ref={innerRef} className={pageContainer.valueOf()} style={style} title={tooltip} slot={slot}>
{showHeader && (
<header className={headerClasses.valueOf()}>
{renderCustomHeader && renderCustomHeader()}
{!renderCustomHeader && this.renderHeader()}
</header>
)}
<section className={classes.contentSection}>{children}</section>
{showFooter && (
<footer className={footerClasses.valueOf()}>{renderCustomFooter && renderCustomFooter()}</footer>
)}
</div>
);
return <Bar renderContentLeft={renderBackButton} renderContentMiddle={renderTitle} />;
}, [renderCustomHeader, renderTitle, renderBackButton]);

const pageContainer = StyleClassHelper.of(classes.pageContainer);
const headerClasses = StyleClassHelper.of(classes.pageHeader, classes.baseBar);
const footerClasses = StyleClassHelper.of(classes.pageFooter, classes.baseBar);

if (showHeader) {
pageContainer.put(classes.pageWithHeader);
}
}

if (showFooter) {
pageContainer.put(classes.pageWithFooter);
}

if (className) {
pageContainer.put(className);
}

pageContainer.put(classes[`background${backgroundDesign}`]);

return (
<div ref={ref} className={pageContainer.valueOf()} style={style} title={tooltip} slot={slot}>
{showHeader && <header className={headerClasses.valueOf()}>{header}</header>}
<section className={classes.contentSection}>{children}</section>
{showFooter && <footer className={footerClasses.valueOf()}>{renderCustomFooter && renderCustomFooter()}</footer>}
</div>
);
});

Page.defaultProps = {
showHeader: true,
showFooter: false,
showBackButton: true,
renderCustomHeader: null,
renderCustomFooter: null,
title: '',
backgroundDesign: PageBackgroundDesign.Standard
};

Page.displayName = 'Page';

export { Page };