From 6e7c8e0f092ee7846649c26df795cacdb4a6a1ed Mon Sep 17 00:00:00 2001 From: Frederick O'Brien Date: Wed, 10 Jun 2026 18:09:02 +0100 Subject: [PATCH] Move ShowcaseLayout to grid --- dotcom-rendering/src/layouts/DecideLayout.tsx | 5 +- .../src/layouts/ShowcaseLayout.tsx | 917 ------------------ .../src/layouts/StandardLayout.tsx | 17 +- ...Arrangements.ts => articleArrangements.ts} | 36 +- 4 files changed, 50 insertions(+), 925 deletions(-) delete mode 100644 dotcom-rendering/src/layouts/ShowcaseLayout.tsx rename dotcom-rendering/src/layouts/lib/{furnitureArrangements.ts => articleArrangements.ts} (84%) diff --git a/dotcom-rendering/src/layouts/DecideLayout.tsx b/dotcom-rendering/src/layouts/DecideLayout.tsx index 8188ce304ed..b6dd7f4a27c 100644 --- a/dotcom-rendering/src/layouts/DecideLayout.tsx +++ b/dotcom-rendering/src/layouts/DecideLayout.tsx @@ -15,7 +15,6 @@ import { InteractiveLayout } from './InteractiveLayout'; import { LiveLayout } from './LiveLayout'; import { NewsletterSignupLayout } from './NewsletterSignupLayout'; import { PictureLayout } from './PictureLayout'; -import { ShowcaseLayout } from './ShowcaseLayout'; import { StandardLayout } from './StandardLayout'; interface BaseProps { @@ -103,7 +102,7 @@ const DecideLayoutApps = ({ article, renderingTarget }: AppProps) => { ); default: return ( - { ); default: return ( - ( -
- {children} -
-); - -const maxWidth = css` - ${from.desktop} { - max-width: 620px; - } -`; - -const fullHeight = css` - height: 100%; -`; - -const stretchLines = css` - ${until.phablet} { - margin-left: -20px; - margin-right: -20px; - } - ${until.mobileLandscape} { - margin-left: -10px; - margin-right: -10px; - } -`; -const mainMediaWrapper = css` - position: relative; -`; - -const PositionHeadline = ({ - design, - children, -}: { - design: ArticleDesign; - children: React.ReactNode; -}) => { - switch (design) { - case ArticleDesign.Interview: - return ( -
-
{children}
-
- ); - default: - return
{children}
; - } -}; - -interface CommonProps { - article: ArticleDeprecated; - format: ArticleFormat; - renderingTarget: RenderingTarget; - serverTime?: number; -} - -interface WebProps extends CommonProps { - NAV: NavType; - renderingTarget: 'Web'; -} - -interface AppsProps extends CommonProps { - renderingTarget: 'Apps'; -} - -export const ShowcaseLayout = (props: WebProps | AppsProps) => { - const { article, format, renderingTarget, serverTime } = props; - const { - config: { isPaidContent, host, hasSurveyAd }, - editionId, - } = article; - const isWeb = renderingTarget === 'Web'; - const isApps = renderingTarget === 'Apps'; - - const showBodyEndSlot = - isWeb && - (parse(article.slotMachineFlags ?? '').showBodyEnd || - article.config.switches.slotBodyEnd); - - // TODO: - // 1) Read 'forceEpic' value from URL parameter and use it to force the slot to render - // 2) Otherwise, ensure slot only renders if `article.config.shouldHideReaderRevenue` equals false. - - const showComments = article.isCommentable && !isPaidContent; - - const { branding } = article.commercialProperties[article.editionId]; - - const contributionsServiceUrl = getContributionsServiceUrl(article); - - const isWorldCup2026 = article.tags.some((tag) => tag.id === worldCupTagId); - - const renderAds = canRenderAds(article); - - const isLabs = format.theme === ArticleSpecial.Labs; - - return ( - <> - {isWeb && ( - <> - {!isLabs ? ( -
- {renderAds && ( - -
- -
-
- )} - - tag.id)} - sectionId={article.config.section} - contentType={article.contentType} - /> -
- ) : ( - // Else, this is a labs article so just show Nav and the Labs header - <> -
- {renderAds && ( - -
- -
-
- )} - - tag.id, - )} - sectionId={article.config.section} - contentType={article.contentType} - /> - -
- -
- -
-
- - )} - - )} - - {isWeb && renderAds && hasSurveyAd && ( - - )} - -
- {isApps && renderAds && ( - - - - )} - -
- - -
- -
-
- - - - - - - - - - - - - - {/* Only show Listen to Article button on App landscape views */} - {isApps && ( - -
- - - -
-
- )} -
- -
-
- -
-
-
- {isApps ? ( - <> - - - - - - {!!article.affiliateLinksDisclaimer && ( - - )} - - - ) : ( - <> - - {!!article.affiliateLinksDisclaimer && ( - - )} - - )} -
-
- - - - {showBodyEndSlot && ( - - - - )} - - - - - -
- - - - - -
-
-
-
- - {isWeb && renderAds && !isLabs && ( -
- -
- )} - - {article.storyPackage && ( -
- - - -
- )} - - - - - - {showComments && ( -
- -
- )} - - {!isPaidContent && ( -
- - - - - -
- )} - - {isWeb && renderAds && !isLabs && ( -
- -
- )} -
- {isWeb && props.NAV.subNavSections && ( -
- - - -
- )} - {isWeb && ( - <> -
-
-
- - - - - - - - - )} - {isApps && ( -
- - - -
- )} - - ); -}; diff --git a/dotcom-rendering/src/layouts/StandardLayout.tsx b/dotcom-rendering/src/layouts/StandardLayout.tsx index f3cff15e8e0..4942ac6c129 100644 --- a/dotcom-rendering/src/layouts/StandardLayout.tsx +++ b/dotcom-rendering/src/layouts/StandardLayout.tsx @@ -46,6 +46,7 @@ import { SubNav } from '../components/SubNav.island'; import { grid } from '../grid'; import { ArticleDesign, + ArticleDisplay, type ArticleFormat, ArticleSpecial, } from '../lib/articleFormat'; @@ -64,7 +65,7 @@ import { type Area, gridItemCss, type LayoutType, -} from './lib/furnitureArrangements'; +} from './lib/articleArrangements'; import { BannerWrapper, Stuck } from './lib/stickiness'; const stretchLines = css` @@ -164,6 +165,8 @@ export const StandardLayout = (props: WebProps | AppProps) => { const isVideo = format.design === ArticleDesign.Video; + const isShowcase = format.display === ArticleDisplay.Showcase; + const showComments = article.isCommentable && !isPaidContent; const { branding } = article.commercialProperties[article.editionId]; @@ -176,7 +179,11 @@ export const StandardLayout = (props: WebProps | AppProps) => { const renderAds = canRenderAds(article); - const layoutType: LayoutType = isMedia ? 'media' : 'standard'; + const layoutType: LayoutType = isMedia + ? 'media' + : isShowcase + ? 'showcase' + : 'standard'; return ( <> @@ -246,7 +253,7 @@ export const StandardLayout = (props: WebProps | AppProps) => { )} -
+
{isApps && renderAds && ( @@ -288,7 +295,9 @@ export const StandardLayout = (props: WebProps | AppProps) => { hideCaption={isMedia} shouldHideAds={article.shouldHideAds} contentType={article.contentType} - contentLayout="StandardLayout" + contentLayout={`${ + ArticleDisplay[format.display] + }Layout`} /> = { standard: standardCss, + showcase: showcaseCss, media: mediaCss, };