diff --git a/src/elements/content-preview/ContentPreview.js b/src/elements/content-preview/ContentPreview.js index 7bf6b8f0e3..a23f5360b0 100644 --- a/src/elements/content-preview/ContentPreview.js +++ b/src/elements/content-preview/ContentPreview.js @@ -137,7 +137,9 @@ type Props = { hasProviders?: boolean, hideSidebar?: boolean, isComparing?: boolean, + banner?: React.Node, comparedSlotRef?: (?HTMLDivElement) => mixed, + comparedBanner?: React.Node, comparedVersion?: BoxItemVersion, isLarge: boolean, isVeryLarge?: boolean, @@ -1727,6 +1729,7 @@ class ContentPreview extends React.PureComponent { hasHeader, hasProviders, hideSidebar, + banner, comparedSlotRef, isComparing, history, @@ -1830,6 +1833,7 @@ class ContentPreview extends React.PureComponent { onMouseMove={this.onMouseMove} ref={this.containerRef} > + {banner &&
{banner}
} {file && ( {({ measureRef: previewRef }) => { @@ -1932,7 +1936,7 @@ const ConnectedContentPreview = flow([ const MemoConnectedContentPreview = React.memo(ConnectedContentPreview); function ContentPreviewWithComparison(props: ContentPreviewProps) { - const { comparedVersion, ...rest } = props; + const { comparedBanner, comparedVersion, ...rest } = props; const [comparedSlot, setComparedSlot] = React.useState(null); const comparedVersionId = comparedVersion && comparedVersion.id; const isComparing = comparedVersionId != null && comparedVersionId !== ''; @@ -1953,6 +1957,7 @@ function ContentPreviewWithComparison(props: ContentPreviewProps) { accessPattern={undefined} advancedContentInsights={undefined} autoFocus={false} + banner={comparedBanner} boxAnnotations={undefined} collection={EMPTY_COLLECTION} componentRef={undefined} diff --git a/src/elements/content-preview/ContentPreview.scss b/src/elements/content-preview/ContentPreview.scss index 23c9c81fd0..a9ba9b9126 100644 --- a/src/elements/content-preview/ContentPreview.scss +++ b/src/elements/content-preview/ContentPreview.scss @@ -13,6 +13,15 @@ &--comparing > .bcpr-container { flex: 1 1 50%; min-width: 0; + + // Hosts set --bcpr-*-pane-background (e.g. preview-client). + // Unset vars keep BCP's .bp default (#f5f5f5). Skip .bp-dark (video). + // 3D is .bp-box3d and gets the host fill. + .bp:not(.bp-dark), + .bp-doc, + .bp-document-preload-wrapper { + background-color: var(--bcpr-current-pane-background, #f5f5f5); + } } } @@ -21,6 +30,7 @@ flex: 1 1 50%; min-width: 0; min-height: 0; + background-color: var(--bcpr-compared-pane-background, #f5f5f5); &:not(:empty) { display: flex; @@ -31,16 +41,44 @@ min-width: 0; min-height: 0; } + + .bp:not(.bp-dark), + .bp-doc, + .bp-document-preload-wrapper { + background-color: var(--bcpr-compared-pane-background, #f5f5f5); + } } .bcpr-container { position: relative; display: flex; flex: 1; + flex-direction: column; + min-height: 0; + } + + .bcpr-banner { + position: absolute; + top: 0; + right: 0; + left: 0; + z-index: 1; + } + + // Hosts set --bcpr-banner-height so the overlay does not cover the first page or thumbnail. + .bcpr-container:has(.bcpr-banner) { + .pdfViewer { + padding-top: var(--bcpr-banner-height); + } + + .bp-vs-list { + margin-top: var(--bcpr-banner-height); + } } .bcpr-content { flex: 1; + min-height: 0; } .bp-navigate { @@ -105,6 +143,11 @@ position: static; } + // Compared instance is not --comparing. Keep the banner's containing block. + .bcpr-body:not(.bcpr-body--comparing) .bcpr-container:has(.bcpr-banner) { + position: relative; + } + &.bcpr-thumbnails-open .bcpr-navigate-left { left: 0; } diff --git a/src/elements/content-preview/__tests__/ContentPreview.test.js b/src/elements/content-preview/__tests__/ContentPreview.test.js index f919cf17ba..830109a970 100644 --- a/src/elements/content-preview/__tests__/ContentPreview.test.js +++ b/src/elements/content-preview/__tests__/ContentPreview.test.js @@ -2802,6 +2802,57 @@ describe('elements/content-preview/ContentPreview', () => { expect(bodyDiv.find('.bcpr-compared-slot').exists()).toBe(false); }); + test('should render the banner above the viewer content when provided', () => { + const wrapper = getWrapper({ + banner:
v12
, + fileId: '123', + }); + wrapper.setState({ + currentFileId: '123', + file: { id: '123', name: 'test.pdf' }, + }); + + const container = wrapper.find('.bcpr-container'); + const bannerDiv = container.children().at(0); + expect(bannerDiv.hasClass('bcpr-banner')).toBe(true); + expect(bannerDiv.find('.test-banner').exists()).toBe(true); + }); + + test('should not render a banner element when the banner prop is omitted', () => { + const wrapper = getWrapper({ + fileId: '123', + }); + wrapper.setState({ + currentFileId: '123', + file: { id: '123', name: 'test.pdf' }, + }); + + expect(wrapper.find('.bcpr-banner').exists()).toBe(false); + }); + + test('should forward comparedBanner as the compared instance banner only', () => { + const banner =
; + const comparedBanner =
; + const wrapper = shallow( + , + ); + + wrapper.childAt(0).props().comparedSlotRef(document.createElement('div')); + wrapper.update(); + + const mainProps = wrapper.childAt(0).props(); + const comparedProps = wrapper.childAt(1).props().children.props; + expect(mainProps.banner).toBe(banner); + expect(mainProps.comparedBanner).toBeUndefined(); + expect(comparedProps.banner).toBe(comparedBanner); + }); + test('should not render PreviewNavigation when isComparing', () => { const wrapper = getWrapper({ fileId: '456',