diff --git a/dotcom-rendering/src/components/Avatar.tsx b/dotcom-rendering/src/components/Avatar.tsx index 6c69acb3e0e..9ebdef9fc43 100644 --- a/dotcom-rendering/src/components/Avatar.tsx +++ b/dotcom-rendering/src/components/Avatar.tsx @@ -57,17 +57,19 @@ type Props = { alt: string; shape?: AvatarShape; imageSize?: MediaSizeType; + isInAllBoostsTest?: boolean; }; const decideImageWidths = ( imageSize: MediaSizeType, + isInAllBoostsTest = false, ): [ImageWidthType, ...ImageWidthType[]] => { switch (imageSize) { case 'small': return [ { breakpoint: breakpoints.mobile, - width: 80, + width: isInAllBoostsTest ? 150 : 80, aspectRatio: '1:1', }, ]; @@ -142,9 +144,15 @@ const defaultImageSizes: [ImageWidthType, ...ImageWidthType[]] = [ { breakpoint: breakpoints.tablet, width: 140 }, ]; -export const Avatar = ({ src, alt, shape = 'round', imageSize }: Props) => { +export const Avatar = ({ + src, + alt, + shape = 'round', + imageSize, + isInAllBoostsTest, +}: Props) => { const imageWidths = imageSize - ? decideImageWidths(imageSize) + ? decideImageWidths(imageSize, isInAllBoostsTest) : defaultImageSizes; const sources = generateSources(getSourceImageUrl(src), imageWidths); diff --git a/dotcom-rendering/src/components/Card/Card.tsx b/dotcom-rendering/src/components/Card/Card.tsx index b7ac1d0dc11..98c585fd5ae 100644 --- a/dotcom-rendering/src/components/Card/Card.tsx +++ b/dotcom-rendering/src/components/Card/Card.tsx @@ -155,6 +155,8 @@ export type Props = { trailTextSize?: TrailTextSize; /** A kicker image is seperate to the main media and renders as part of the kicker */ showKickerImage?: boolean; + isInAllBoostsTest?: boolean; + fixImageWidth?: boolean; /** Determines if the headline should be positioned within the content or outside the content */ headlinePosition?: 'inner' | 'outer'; /** Feature flag for the labs redesign work */ @@ -395,6 +397,8 @@ export const Card = ({ showTopBarMobile = true, trailTextSize, showKickerImage = false, + fixImageWidth, + isInAllBoostsTest = false, headlinePosition = 'inner', showLabsRedesign = false, }: Props) => { @@ -581,12 +585,14 @@ export const Card = ({ containerType === 'flexible/special' || containerType === 'flexible/general'; - const isSmallCard = containerType === 'scrollable/small'; + const isSmallCard = + containerType === 'scrollable/small' || + containerType === 'scrollable/medium'; const mediaFixedSizeOptions = (): MediaFixedSizeOptions => { if (isSmallCard) { return { - mobile: 'tiny', + mobile: isInAllBoostsTest ? undefined : 'tiny', tablet: 'small', desktop: 'small', }; @@ -883,6 +889,11 @@ export const Card = ({ mediaType={media.type} mediaPositionOnDesktop={mediaPositionOnDesktop} mediaPositionOnMobile={mediaPositionOnMobile} + fixImageWidth={ + fixImageWidth ?? + (mediaPositionOnMobile === 'left' || + mediaPositionOnMobile === 'right') + } hideImageOverlay={media.type === 'slideshow'} padMedia={isMediaCardOrNewsletter && isBetaContainer} isBetaContainer={isBetaContainer} @@ -915,6 +926,7 @@ export const Card = ({ imagePositionOnMobile={mediaPositionOnMobile} isBetaContainer={isBetaContainer} isFlexibleContainer={isFlexibleContainer} + isInAllBoostsTest={isInAllBoostsTest} > )} @@ -1042,6 +1055,9 @@ export const Card = ({ loading={imageLoading} roundedCorners={isOnwardContent} aspectRatio={aspectRatio} + isInAllBoostsTest={ + isInAllBoostsTest + } /> )} @@ -1056,6 +1072,7 @@ export const Card = ({ loading={imageLoading} roundedCorners={isOnwardContent} aspectRatio={aspectRatio} + isInAllBoostsTest={isInAllBoostsTest} /> {isVideoMainMedia && mainMedia.duration > 0 && (
)} diff --git a/dotcom-rendering/src/components/Card/components/AvatarContainer.tsx b/dotcom-rendering/src/components/Card/components/AvatarContainer.tsx index 2087e894fb0..a620b768354 100644 --- a/dotcom-rendering/src/components/Card/components/AvatarContainer.tsx +++ b/dotcom-rendering/src/components/Card/components/AvatarContainer.tsx @@ -9,6 +9,7 @@ type Props = { imagePositionOnMobile: MediaPositionType; isBetaContainer: boolean; isFlexibleContainer: boolean; + isInAllBoostsTest?: boolean; }; const sideMarginStyles = css` @@ -31,6 +32,7 @@ const sizingStyles = ( isFlexibleContainer: boolean, isVerticalOnDesktop: boolean, isVerticalOnMobile: boolean, + isInAllBoostsTest = false, ) => { if (!isBetaContainer) { switch (imageSize) { @@ -81,6 +83,26 @@ const sizingStyles = ( switch (imageSize) { case 'small': + if (isInAllBoostsTest) { + return isFlexibleContainer + ? css` + width: 90px; + height: 90px; + ${until.tablet} { + height: 150px; + width: 150px; + } + ` + : css` + width: 80px; + height: 80px; + ${until.tablet} { + height: 150px; + width: 150px; + } + `; + } + return isFlexibleContainer ? css` width: 90px; @@ -137,6 +159,7 @@ export const AvatarContainer = ({ imagePositionOnMobile, isBetaContainer, isFlexibleContainer, + isInAllBoostsTest, }: Props) => { const isVerticalOnDesktop = imagePositionOnDesktop === 'top' || imagePositionOnDesktop === 'bottom'; @@ -155,6 +178,7 @@ export const AvatarContainer = ({ isFlexibleContainer, isVerticalOnDesktop, isVerticalOnMobile, + isInAllBoostsTest, ), ]} > diff --git a/dotcom-rendering/src/components/Card/components/MediaWrapper.tsx b/dotcom-rendering/src/components/Card/components/MediaWrapper.tsx index ba22e96ad3a..a7a2b340fd4 100644 --- a/dotcom-rendering/src/components/Card/components/MediaWrapper.tsx +++ b/dotcom-rendering/src/components/Card/components/MediaWrapper.tsx @@ -12,7 +12,7 @@ const mediaFixedSize = { type MediaFixedSize = keyof typeof mediaFixedSize; export type MediaFixedSizeOptions = { - mobile: MediaFixedSize; + mobile?: MediaFixedSize; tablet?: MediaFixedSize; desktop?: MediaFixedSize; }; @@ -38,6 +38,7 @@ type Props = { mediaType?: CardMediaType; mediaPositionOnDesktop: MediaPositionType; mediaPositionOnMobile: MediaPositionType; + fixImageWidth: boolean; /** * Forces hiding the image overlay added to pictures & slideshows on hover. * This is to allow hiding the overlay on slideshow carousels where we don't @@ -166,7 +167,7 @@ const fixMediaWidth = ({ desktop, }: MediaFixedSizeOptions) => css` ${until.tablet} { - ${fixMediaWidthStyles(mediaFixedSize[mobile])} + ${mobile !== undefined && fixMediaWidthStyles(mediaFixedSize[mobile])} } ${tablet && css` @@ -189,14 +190,13 @@ export const MediaWrapper = ({ mediaType, mediaPositionOnDesktop, mediaPositionOnMobile, + fixImageWidth, hideImageOverlay, isBetaContainer = false, padMedia, }: Props) => { const isHorizontalOnDesktop = mediaPositionOnDesktop === 'left' || mediaPositionOnDesktop === 'right'; - const isHorizontalOnMobile = - mediaPositionOnMobile === 'left' || mediaPositionOnMobile === 'right'; return (
{ switch (imageSize) { // @TODO missing image size option @@ -52,7 +54,11 @@ const decideImageWidths = ( case 'small': return [ - { breakpoint: breakpoints.mobile, width: 120, aspectRatio }, + { + breakpoint: breakpoints.mobile, + width: isInAllBoostsTest ? 465 : 120, + aspectRatio, + }, { breakpoint: breakpoints.tablet, width: 160, aspectRatio }, { breakpoint: breakpoints.desktop, width: 220, aspectRatio }, ]; @@ -210,6 +216,7 @@ export const CardPicture = ({ isCircular, aspectRatio = '5:3', mobileAspectRatio, + isInAllBoostsTest = false, }: Props) => { if (mainImage === '') { return null; @@ -217,7 +224,7 @@ export const CardPicture = ({ const sources = generateSources( mainImage, - decideImageWidths(imageSize, aspectRatio), + decideImageWidths(imageSize, aspectRatio, isInAllBoostsTest), ); const fallbackSource = getFallbackSource(sources); diff --git a/dotcom-rendering/src/components/DecideContainer.tsx b/dotcom-rendering/src/components/DecideContainer.tsx index efc50b4fe62..13e3de7656a 100644 --- a/dotcom-rendering/src/components/DecideContainer.tsx +++ b/dotcom-rendering/src/components/DecideContainer.tsx @@ -46,6 +46,7 @@ type Props = { sectionId: string; frontId?: string; collectionId: number; + isInAllBoostsTest?: boolean; containerLevel?: DCRContainerLevel; /** Feature flag for the labs redesign work */ showLabsRedesign?: boolean; @@ -63,6 +64,7 @@ export const DecideContainer = ({ sectionId, frontId, collectionId, + isInAllBoostsTest, containerLevel, showLabsRedesign = false, }: Props) => { @@ -246,6 +248,7 @@ export const DecideContainer = ({ absoluteServerTimes={absoluteServerTimes} imageLoading={imageLoading} aspectRatio={aspectRatio} + isInAllBoostsTest={!!isInAllBoostsTest} collectionId={collectionId} showLabsRedesign={!!showLabsRedesign} /> @@ -260,39 +263,66 @@ export const DecideContainer = ({ imageLoading={imageLoading} aspectRatio={aspectRatio} containerLevel={containerLevel} + isInAllBoostsTest={!!isInAllBoostsTest} collectionId={collectionId} showLabsRedesign={!!showLabsRedesign} /> ); case 'scrollable/small': - return ( + return isInAllBoostsTest ? ( + + ) : ( ); case 'scrollable/medium': - return ( + return isInAllBoostsTest ? ( + + ) : ( ); @@ -306,6 +336,7 @@ export const DecideContainer = ({ imageLoading={imageLoading} aspectRatio={aspectRatio} showLabsRedesign={!!showLabsRedesign} + isInAllBoostsTest={isInAllBoostsTest} /> ); case 'scrollable/feature': diff --git a/dotcom-rendering/src/components/FlexibleGeneral.tsx b/dotcom-rendering/src/components/FlexibleGeneral.tsx index f04077e888e..658b4aa2d9d 100644 --- a/dotcom-rendering/src/components/FlexibleGeneral.tsx +++ b/dotcom-rendering/src/components/FlexibleGeneral.tsx @@ -34,6 +34,7 @@ type Props = { collectionId: number; /** Feature flag for the labs redesign work */ showLabsRedesign?: boolean; + isInAllBoostsTest?: boolean; }; type RowLayout = 'oneCardHalfWidth' | 'oneCardFullWidth' | 'twoCard'; @@ -507,6 +508,7 @@ type HalfWidthCardLayoutProps = { absoluteServerTimes: boolean; aspectRatio: AspectRatio; isLastRow: boolean; + isInAllBoostsTest?: boolean; containerLevel: DCRContainerLevel; /** Feature flag for the labs redesign work */ showLabsRedesign?: boolean; @@ -522,6 +524,7 @@ const HalfWidthCardLayout = ({ isFirstStandardRow, aspectRatio, isLastRow, + isInAllBoostsTest, containerLevel, showLabsRedesign, }: HalfWidthCardLayoutProps) => { @@ -557,6 +560,9 @@ const HalfWidthCardLayout = ({ image={card.image} imageLoading={imageLoading} mediaPositionOnDesktop="left" + mediaPositionOnMobile={ + isInAllBoostsTest ? 'bottom' : 'left' + } supportingContent={card.supportingContent?.slice( 0, 2, @@ -575,9 +581,18 @@ const HalfWidthCardLayout = ({ (containerLevel !== 'Primary' && cardIndex > 0) } trailText={undefined} - headlineSizes={undefined} + headlineSizes={ + isInAllBoostsTest + ? { + desktop: 'xsmall', + tablet: 'xxsmall', + mobile: 'small', + } + : undefined + } canPlayInline={false} showLabsRedesign={showLabsRedesign} + isInAllBoostsTest={isInAllBoostsTest} /> ); @@ -594,6 +609,7 @@ export const FlexibleGeneral = ({ imageLoading, aspectRatio, containerLevel = 'Primary', + isInAllBoostsTest = false, collectionId, showLabsRedesign, }: Props) => { @@ -661,6 +677,7 @@ export const FlexibleGeneral = ({ isFirstStandardRow={i === 0} aspectRatio={aspectRatio} isLastRow={i === groupedCards.length - 1} + isInAllBoostsTest={isInAllBoostsTest} containerLevel={containerLevel} showLabsRedesign={showLabsRedesign} /> diff --git a/dotcom-rendering/src/components/FlexibleSpecial.tsx b/dotcom-rendering/src/components/FlexibleSpecial.tsx index be17a259762..93d7721ce87 100644 --- a/dotcom-rendering/src/components/FlexibleSpecial.tsx +++ b/dotcom-rendering/src/components/FlexibleSpecial.tsx @@ -29,6 +29,7 @@ type Props = { absoluteServerTimes: boolean; aspectRatio: AspectRatio; containerLevel?: DCRContainerLevel; + isInAllBoostsTest?: boolean; collectionId: number; showLabsRedesign?: boolean; }; @@ -223,6 +224,7 @@ type TwoOrFourCardLayoutProps = { containerLevel: DCRContainerLevel; /** Feature flag for the labs redesign work */ showLabsRedesign?: boolean; + isInAllBoostsTest: boolean; }; const TwoOrFourCardLayout = ({ @@ -236,6 +238,7 @@ const TwoOrFourCardLayout = ({ isFirstRow, containerLevel, showLabsRedesign, + isInAllBoostsTest, }: TwoOrFourCardLayoutProps) => { if (cards.length === 0) return null; const hasTwoOrFewerCards = cards.length <= 2; @@ -263,6 +266,19 @@ const TwoOrFourCardLayout = ({ hasTwoOrFewerCards, isMediaCard(card.format) || !!card.isNewsletter, )} + mediaPositionOnMobile={ + isInAllBoostsTest ? 'bottom' : 'left' + } + headlineSizes={ + isInAllBoostsTest + ? { + desktop: 'xsmall', + tablet: 'xxsmall', + mobile: 'small', + } + : undefined + } + isInAllBoostsTest={isInAllBoostsTest} /* we don't want to support sublinks on standard cards here so we hard code to undefined */ supportingContent={undefined} mediaSize="small" @@ -293,6 +309,7 @@ export const FlexibleSpecial = ({ imageLoading, aspectRatio, containerLevel = 'Primary', + isInAllBoostsTest = false, collectionId, showLabsRedesign, }: Props) => { @@ -351,6 +368,7 @@ export const FlexibleSpecial = ({ isFirstRow={!isNonEmptyArray(snaps) && !isNonEmptyArray(splash)} containerLevel={containerLevel} showLabsRedesign={showLabsRedesign} + isInAllBoostsTest={isInAllBoostsTest} /> ); diff --git a/dotcom-rendering/src/components/ScrollableMedium.importable.tsx b/dotcom-rendering/src/components/ScrollableMedium.importable.tsx index 2041d36b7b3..77dc0c3cf7b 100644 --- a/dotcom-rendering/src/components/ScrollableMedium.importable.tsx +++ b/dotcom-rendering/src/components/ScrollableMedium.importable.tsx @@ -1,10 +1,13 @@ import { isMediaCard } from '../lib/cardHelpers'; +import { palette } from '../palette'; import type { AspectRatio, + DCRContainerLevel, DCRContainerPalette, - DCRContainerType, DCRFrontCard, } from '../types/front'; +import { LI } from './Card/components/LI'; +import { UL } from './Card/components/UL'; import { FrontCard } from './FrontCard'; import { ScrollableCarousel } from './ScrollableCarousel'; @@ -14,11 +17,12 @@ type Props = { showAge?: boolean; absoluteServerTimes: boolean; imageLoading: 'lazy' | 'eager'; - containerType: DCRContainerType; aspectRatio: AspectRatio; sectionId: string; + containerLevel?: DCRContainerLevel; /** Feature flag for the labs redesign work */ showLabsRedesign?: boolean; + isInAllBoostsTest?: boolean; }; /** @@ -31,14 +35,71 @@ type Props = { export const ScrollableMedium = ({ trails, containerPalette, - containerType, absoluteServerTimes, imageLoading, showAge, aspectRatio, sectionId, + containerLevel, showLabsRedesign, + isInAllBoostsTest = false, }: Props) => { + if (isInAllBoostsTest) { + return ( +
    + {trails.map((trail, index) => { + const imagePosition = isMediaCard(trail.format) + ? 'top' + : 'bottom'; + + return ( +
  • + 0) + } + isInAllBoostsTest={isInAllBoostsTest} + canPlayInline={false} + showLabsRedesign={showLabsRedesign} + /> +
  • + ); + })} +
+ ); + } + return ( ( diff --git a/dotcom-rendering/src/components/ScrollableSmall.importable.tsx b/dotcom-rendering/src/components/ScrollableSmall.importable.tsx index 89cfbf0bfb4..bde287862bb 100644 --- a/dotcom-rendering/src/components/ScrollableSmall.importable.tsx +++ b/dotcom-rendering/src/components/ScrollableSmall.importable.tsx @@ -1,9 +1,13 @@ +import { css } from '@emotion/react'; +import { from } from '@guardian/source/foundations'; +import { palette } from '../palette'; import type { AspectRatio, DCRContainerPalette, - DCRContainerType, DCRFrontCard, } from '../types/front'; +import { LI } from './Card/components/LI'; +import { UL } from './Card/components/UL'; import { FrontCard } from './FrontCard'; import { ScrollableCarousel } from './ScrollableCarousel'; @@ -13,8 +17,8 @@ type Props = { showAge?: boolean; absoluteServerTimes?: boolean; imageLoading: 'lazy' | 'eager'; - containerType: DCRContainerType; aspectRatio: AspectRatio; + isInAllBoostsTest?: boolean; sectionId: string; /** Feature flag for the labs redesign work */ showLabsRedesign?: boolean; @@ -56,17 +60,127 @@ type Props = { export const ScrollableSmall = ({ trails, containerPalette, - containerType, absoluteServerTimes, imageLoading, showAge, aspectRatio, + isInAllBoostsTest = false, sectionId, showLabsRedesign, }: Props) => { const mobileBottomCards = [1, 3]; const desktopBottomCards = [2, 3]; + if (isInAllBoostsTest) { + return ( + <> +
    + {trails.slice(0, 2).map((trail, index) => { + return ( +
  • + +
  • + ); + })} +
+
+
    + {trails.slice(2, 4).map((trail, index) => { + return ( +
  • + +
  • + ); + })} +
+ + ); + } + return ( ( diff --git a/dotcom-rendering/src/components/StaticMediumFour.tsx b/dotcom-rendering/src/components/StaticMediumFour.tsx index 85718ac3033..6573662c6a7 100644 --- a/dotcom-rendering/src/components/StaticMediumFour.tsx +++ b/dotcom-rendering/src/components/StaticMediumFour.tsx @@ -34,6 +34,7 @@ type Props = { containerLevel?: DCRContainerLevel; /** Feature flag for the labs redesign work */ showLabsRedesign?: boolean; + isInAllBoostsTest?: boolean; }; export const StaticMediumFour = ({ @@ -46,6 +47,7 @@ export const StaticMediumFour = ({ aspectRatio, containerLevel = 'Primary', showLabsRedesign, + isInAllBoostsTest = false, }: Props) => { const cards = trails.slice(0, 4); @@ -55,7 +57,7 @@ export const StaticMediumFour = ({ return (
  • 0} @@ -72,6 +74,18 @@ export const StaticMediumFour = ({ card.format, !!card.isNewsletter, )} + mediaPositionOnMobile={ + isInAllBoostsTest ? 'bottom' : 'left' + } + headlineSizes={ + isInAllBoostsTest + ? { + desktop: 'xsmall', + tablet: 'xxsmall', + mobile: 'small', + } + : undefined + } /* we don't want to support sublinks on standard cards here so we hard code to undefined */ supportingContent={undefined} mediaSize="medium" @@ -86,6 +100,7 @@ export const StaticMediumFour = ({ } canPlayInline={false} showLabsRedesign={showLabsRedesign} + isInAllBoostsTest={isInAllBoostsTest} />
  • ); diff --git a/dotcom-rendering/src/layouts/FrontLayout.tsx b/dotcom-rendering/src/layouts/FrontLayout.tsx index 76bd8ab93d5..cee6fa68b1c 100644 --- a/dotcom-rendering/src/layouts/FrontLayout.tsx +++ b/dotcom-rendering/src/layouts/FrontLayout.tsx @@ -105,6 +105,7 @@ export const FrontLayout = ({ front, NAV }: Props) => { isPaidContent, hasPageSkin: hasPageSkinConfig, pageId, + abTests, switches: { absoluteServerTimes = false }, }, editionId, @@ -601,6 +602,10 @@ export const FrontLayout = ({ front, NAV }: Props) => { } sectionId={ophanName} collectionId={index + 1} + isInAllBoostsTest={ + front.isNetworkFront && + abTests.allBoostsVariant === 'variant' + } containerLevel={collection.containerLevel} showLabsRedesign={showLabsRedesign} />