wix-style-react
Version:
wix-style-react
149 lines • 8.59 kB
JavaScript
import { st, classes } from './PageHeader.st.css';
import React from 'react';
import PropTypes from 'prop-types';
import { ChevronLeft } from '@wix/wix-ui-icons-common';
import Breadcrumbs from '../Breadcrumbs';
import Text from '../Text';
import Heading from '../Heading';
import IconButton from '../IconButton';
import { dataHooks } from './constants';
import Transition from '../Transition';
import { WixStyleReactContext } from '../WixStyleReactProvider/context';
import { WixStyleReactEnvironmentContext } from '../WixStyleReactEnvironmentProvider/context';
const isDarkTheme = (hasBackgroundImage, minimized, skin) => {
switch (skin) {
case 'light':
return false;
case 'dark':
return true;
default:
return hasBackgroundImage && !minimized;
}
};
const getBreadcrumbsTheme = (hasBackgroundImage, minimized, skin) => isDarkTheme(hasBackgroundImage, minimized, skin)
? 'onDarkBackground'
: 'onGrayBackground';
const getTitle = (title, minimized) => typeof title === 'function' ? title(minimized) : title;
const generateDefaultBreadcrumbs = (title, hasBackgroundImage, minimized, skin) => (React.createElement(Breadcrumbs, { items: [{ id: '1', value: getTitle(title, minimized) }], activeId: "1", size: "medium", theme: getBreadcrumbsTheme(hasBackgroundImage, minimized, skin), onClick: () => { } }));
const getBreadcrumbs = (breadcrumbs, minimized) => typeof breadcrumbs === 'function' ? breadcrumbs(minimized) : breadcrumbs;
const generateThemedBreadcrumbs = (breadcrumbs, title, hasBackgroundImage, minimized, skin) => {
if (breadcrumbs) {
return React.cloneElement(getBreadcrumbs(breadcrumbs, minimized), {
theme: getBreadcrumbsTheme(hasBackgroundImage, minimized, skin),
});
}
return generateDefaultBreadcrumbs(title, hasBackgroundImage, minimized);
};
/**
* A header that sticks at the top of the container which minimizes on scroll
*/
export default class PageHeader extends React.PureComponent {
constructor(props) {
super(props);
this._animateComponent = (show, useEnterDelay, content) => {
if (show) {
return content;
}
return useEnterDelay ? (React.createElement(Transition, { show: show, enterAnimation: {
fadeIn: {
duration: 'medium01',
delay: 'short',
},
}, exitAnimation: {
fadeOut: true,
} }, content)) : (React.createElement(Transition, { show: show, enterAnimation: {
fadeIn: true,
}, exitAnimation: {
fadeOut: true,
} }, content));
};
const { breadcrumbs, title, hasBackgroundImage, minimized, skin } = props;
this.state = {
themedBreadcrumbs: generateThemedBreadcrumbs(breadcrumbs, title, hasBackgroundImage, minimized, skin),
};
}
UNSAFE_componentWillReceiveProps(nextProps) {
const { breadcrumbs, title, hasBackgroundImage, minimized, skin } = this.props;
const newBreadcrumbs = nextProps.breadcrumbs;
const newTitle = nextProps.title;
const newHasBackgroundImage = nextProps.hasBackgroundImage;
const newMinimized = nextProps.minimized;
const newSkin = nextProps.skin;
if (breadcrumbs !== newBreadcrumbs ||
title !== newTitle ||
hasBackgroundImage !== newHasBackgroundImage ||
minimized !== newMinimized ||
skin !== newSkin) {
const themedBreadcrumbs = generateThemedBreadcrumbs(newBreadcrumbs, newTitle, newHasBackgroundImage, newMinimized, skin);
this.setState({ themedBreadcrumbs });
}
}
render() {
const { dataHook, breadcrumbs, onBackClicked, title, subtitle, minimized, skin, actionsBar, showBackButton, hasBackgroundImage, className, } = this.props;
const breadcrumbsExists = !!breadcrumbs;
const { themedBreadcrumbs } = this.state;
const _title = getTitle(title, minimized);
const isDark = isDarkTheme(hasBackgroundImage, minimized, skin);
const { pageHeaderId } = this.context;
return (React.createElement(WixStyleReactContext.Consumer, null, ({ newColorsBranding }) => (React.createElement("div", { className: st(classes.root, {}, className), "data-hook": dataHook },
React.createElement("div", { className: classes.header },
React.createElement("div", null, this._animateComponent(breadcrumbsExists || minimized, !breadcrumbsExists, React.createElement("div", { className: st(classes.breadcrumbsContainer, {
withoutBreadcrumbs: !breadcrumbsExists,
}), "data-hook": dataHooks.breadcrumbs }, themedBreadcrumbs))),
React.createElement("div", { className: st(classes.titleContainer, { minimized }) },
showBackButton &&
onBackClicked &&
this._animateComponent(!minimized, !breadcrumbsExists, React.createElement(IconButton, { className: st(classes.titleBackButton, {
darkTheme: isDark,
newColorsBranding,
}), dataHook: dataHooks.backButton, onClick: onBackClicked },
React.createElement(ChevronLeft, { className: classes.titleBackButtonIcon }))),
React.createElement("div", { className: classes.titleColumn },
title &&
this._animateComponent(!minimized, !breadcrumbsExists, React.createElement(Heading, { size: "extraLarge", className: st(classes.title, { newColorsBranding }), dataHook: dataHooks.title, ellipsis: typeof _title === 'string', light: isDark, id: pageHeaderId }, _title)),
subtitle &&
this._animateComponent(!minimized, !breadcrumbsExists, React.createElement("div", { "data-hook": dataHooks.subtitle },
React.createElement(Text, { ellipsis: typeof subtitle === 'string', light: isDark, secondary: !isDark, maxLines: 2, maxWidth: "288px" }, subtitle)))))),
actionsBar && (React.createElement("div", { className: st(classes.actionsBar, {
minimized,
withBreadcrumbs: breadcrumbsExists,
}), "data-hook": dataHooks.actionBar }, typeof actionsBar === 'function'
? actionsBar({ minimized, hasBackgroundImage, skin })
: actionsBar))))));
}
}
PageHeader.contextType = WixStyleReactEnvironmentContext;
PageHeader.displayName = 'Page.Header';
PageHeader.propTypes = {
/** Applies a data-hook HTML attribute that can be used in the tests */
dataHook: PropTypes.string,
/** Changes header appearance to a denser version. Value changes by the state of the scrolled content inside of a \<Page/>. */
minimized: PropTypes.bool,
/** Inverts header styles. This property is supplied by \<Page/> component and reflects whether \<Page/> has a background image or not. */
hasBackgroundImage: PropTypes.bool,
/** Controls header skin (light or dark) */
skin: PropTypes.oneOf(['light', 'dark']),
/** Specifies a CSS class name to be appended to the component’s root element */
className: PropTypes.string,
/** Adds an empty container above the page title. It accepts any item as a child element, but should be used to pass \<Breadcrumbs/> component only.<br/>
<br/>
For any custom enquiries contact the WSR team first.
*/
breadcrumbs: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
/** Specifies page title text */
title: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
/** Specifies page subtitle text */
subtitle: PropTypes.node,
/** Specifies whether the back button is visible */
showBackButton: PropTypes.bool,
/** Defines a callback function which is called every time a back button is clicked */
onBackClicked: PropTypes.func,
/** Adds an empty container on the right side of a header. Most commonly used to store primary and secondary actions of a page, but can contain any other element, i.e. dropdown selection.<br/>
<br/>
It receives `minimized` and `hasBackgroundImage` props. */
actionsBar: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
};
PageHeader.defaultProps = {
minimized: false,
};
//# sourceMappingURL=PageHeader.js.map