@hackplan/polaris
Version:
Shopify’s product component library
114 lines (113 loc) • 4.85 kB
JavaScript
import * as tslib_1 from "tslib";
import React from 'react';
import isEqual from 'lodash/isEqual';
import { Button as AppBridgeButton, TitleBar as AppBridgeTitleBar, } from '@shopify/app-bridge/actions';
import { classNames } from '../../utilities/css';
import { transformActions, generateRedirect, } from '../../utilities/app-bridge-transformers';
import pick from '../../utilities/pick';
import { withAppProvider } from '../AppProvider';
import { Header } from './components';
import styles from './Page.scss';
const APP_BRIDGE_PROPS = [
'title',
'breadcrumbs',
'secondaryActions',
'actionGroups',
'primaryAction',
];
export class Page extends React.PureComponent {
componentDidMount() {
if (this.delegateToAppbridge === false || !this.props.polaris.appBridge) {
return;
}
const transformedProps = this.transformProps();
if (!transformedProps)
return;
// eslint-disable-next-line no-console
console.warn("Deprecation: Using `Page` to render an embedded app title bar is deprecated and will be removed in v5.0. Use `TitleBar` from `@shopify/app-bridge-react` instead. For example, `import {TitleBar} from '@shopify/app-bridge-react';`");
this.titlebar = AppBridgeTitleBar.create(this.props.polaris.appBridge, transformedProps);
}
componentDidUpdate(prevProps) {
if (this.titlebar == null || this.delegateToAppbridge === false) {
return;
}
const prevAppBridgeProps = pick(prevProps, APP_BRIDGE_PROPS);
const currentAppBridgeProps = pick(this.props, APP_BRIDGE_PROPS);
if (!isEqual(prevAppBridgeProps, currentAppBridgeProps)) {
const transformedProps = this.transformProps();
if (!transformedProps)
return;
this.titlebar.unsubscribe();
this.titlebar.set(transformedProps);
}
}
componentWillUnmount() {
if (this.titlebar == null || this.delegateToAppbridge === false) {
return;
}
this.titlebar.unsubscribe();
}
render() {
const _a = this.props, { children, fullWidth, narrowWidth, singleColumn } = _a, rest = tslib_1.__rest(_a, ["children", "fullWidth", "narrowWidth", "singleColumn"]);
if (singleColumn) {
// eslint-disable-next-line no-console
console.warn('Deprecation: The singleColumn prop has been renamed to narrowWidth to better represents its use and will be removed in v5.0.');
}
const className = classNames(styles.Page, fullWidth && styles.fullWidth, (narrowWidth || singleColumn) && styles.narrowWidth);
const headerMarkup = this.delegateToAppbridge || this.hasHeaderContent() === false ? null : (<Header {...rest}/>);
return (<div className={className}>
{headerMarkup}
<div className={styles.Content}>{children}</div>
</div>);
}
get delegateToAppbridge() {
const { polaris: { appBridge }, forceRender = false, } = this.props;
return appBridge != null && forceRender === false;
}
hasHeaderContent() {
const { title, primaryAction, secondaryActions, actionGroups, breadcrumbs, } = this.props;
return ((title != null && title !== '') ||
primaryAction != null ||
(secondaryActions != null && secondaryActions.length > 0) ||
(actionGroups != null && actionGroups.length > 0) ||
(breadcrumbs != null && breadcrumbs.length > 0));
}
transformProps() {
const { appBridge } = this.props.polaris;
if (!appBridge)
return;
const { title, primaryAction, secondaryActions, actionGroups } = this.props;
return {
title,
buttons: transformActions(appBridge, {
primaryAction,
secondaryActions,
actionGroups,
}),
breadcrumbs: this.transformBreadcrumbs(),
};
}
transformBreadcrumbs() {
const { appBridge } = this.props.polaris;
if (!appBridge)
return;
const { breadcrumbs } = this.props;
if (breadcrumbs != null && breadcrumbs.length > 0) {
const breadcrumb = breadcrumbs[breadcrumbs.length - 1];
const button = AppBridgeButton.create(appBridge, {
label: breadcrumb.content || '',
});
const callback = !('url' in breadcrumb)
? breadcrumb.onAction
: generateRedirect(appBridge, breadcrumb.url, breadcrumb.target);
if (callback != null) {
button.subscribe(AppBridgeButton.Action.CLICK, callback);
}
return button;
}
else {
return undefined;
}
}
}
export default withAppProvider()(Page);