Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
f2d317e
Type tidying
frederickobrien Mar 11, 2026
d087f53
Move all column settings into layout config
frederickobrien Mar 11, 2026
744539d
Remove maxWidth wrapper divs
frederickobrien Mar 11, 2026
6eb25a8
Rough first pass
frederickobrien May 19, 2026
211c9c2
Refactor grid centre rule, more breakpoints
frederickobrien May 21, 2026
6471809
Rough implementation of portrait/landscape variants
frederickobrien May 26, 2026
a87148c
Feature specific styling
frederickobrien Jun 11, 2026
dd62136
Use grid module helpers for columns
frederickobrien Jun 23, 2026
231cf02
First, clumsy pass at immersive forking
frederickobrien Jun 23, 2026
39b646d
Distinguish between feature and non-feature immersives
frederickobrien Jun 30, 2026
86a943f
Fix portrait main media config
frederickobrien Jun 30, 2026
05d9d26
Tie main media styling to article arrangement
frederickobrien Jun 30, 2026
0dafbd3
Restore wrapper
frederickobrien Jul 1, 2026
d67d072
Enhance article meta and layout handling for immersive designs
alessiaAmitrano Jul 7, 2026
4afd212
show byline for immersive landscape
alessiaAmitrano Jul 17, 2026
ec86165
show byline and avatar in a row, show series tag, reintroduce borders…
alessiaAmitrano Jul 21, 2026
d582bd9
add testing for new layoutType parameters influencing contributor sho…
alessiaAmitrano Jul 22, 2026
f92e085
Rough first pass
frederickobrien May 19, 2026
ad4cd74
Rough implementation of portrait/landscape variants
frederickobrien May 26, 2026
1eb6a80
Feature specific styling
frederickobrien Jun 11, 2026
adbec3e
Distinguish between feature and non-feature immersives
frederickobrien Jun 30, 2026
57534d9
Tie main media styling to article arrangement
frederickobrien Jun 30, 2026
2c36282
Rebase tidying
frederickobrien Jul 7, 2026
e33d5d1
Rich review tweaks
frederickobrien Jul 16, 2026
eeaa9ce
Caption grid area and meta section
frederickobrien Jul 21, 2026
b0df0eb
make layoutType optional for ArticleMeta web and app components
alessiaAmitrano Jul 28, 2026
dd4af19
make layoutType optional for ArticleTitle and children
alessiaAmitrano Jul 28, 2026
f020894
Merge remote-tracking branch 'origin/portrait-layout' into aa/portrai…
alessiaAmitrano Jul 28, 2026
7c88363
fix issues post merge
alessiaAmitrano Jul 28, 2026
6739f4c
fix duplicate prop in ArticleHeadline component
alessiaAmitrano Jul 28, 2026
a6a17d7
add changes lost during merge
alessiaAmitrano Jul 29, 2026
b1372f6
Merge commit 'b31f2dfb5958c6710a6ce41054eb29969588e941' into aa/portr…
alessiaAmitrano Jul 29, 2026
7e700b3
remove duplicate identifier
alessiaAmitrano Jul 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion dotcom-rendering/src/components/ArticleHeadline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
until,
} from '@guardian/source/foundations';
import { grid } from '../../src/grid';
import { type LayoutType } from '../layouts/lib/articleArrangements';
import { interactiveLegacyClasses } from '../layouts/lib/interactiveLegacyStyling';
import { getAgeWarning } from '../lib/age-warning';
import {
Expand All @@ -38,13 +39,14 @@
type Props = {
headlineString: string;
format: ArticleFormat;
layoutType?: LayoutType;
byline?: string;
tags: TagType[];
webPublicationDateDeprecated: string;
hasAvatar?: boolean;
isMatch?: boolean;
starRating?: Rating;
isInverted?: boolean;

Check failure on line 49 in dotcom-rendering/src/components/ArticleHeadline.tsx

View workflow job for this annotation

GitHub Actions / lint / check

'isInverted' PropType is defined but prop is never used
};

const topPadding = css`
Expand Down Expand Up @@ -393,14 +395,18 @@
export const ArticleHeadline = ({
headlineString,
format,
layoutType,
tags,
byline,
webPublicationDateDeprecated,
hasAvatar,
isMatch,
starRating,
isInverted,
}: Props) => {
const isInverted =
format.display === ArticleDisplay.Immersive &&
format.design === ArticleDesign.Standard &&
layoutType === 'immersiveLandscapeDefault';
switch (format.display) {
case ArticleDisplay.Immersive: {
switch (format.design) {
Expand Down
7 changes: 5 additions & 2 deletions dotcom-rendering/src/components/ArticleMeta.apps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { from, space, until } from '@guardian/source/foundations';
import { StraightLines } from '@guardian/source-development-kitchen/react-components';
import type { ReactNode } from 'react';
import { grid } from '../grid';
import type { LayoutType } from '../layouts/lib/articleArrangements';
import { interactiveLegacyClasses } from '../layouts/lib/interactiveLegacyStyling';
import {
ArticleDesign,
Expand Down Expand Up @@ -36,6 +37,7 @@ import { PodcastMeta } from './PodcastMeta';

type Props = {
format: ArticleFormat;
layoutType?: LayoutType;
byline?: string;
tags: TagType[];
primaryDateline: string;
Expand Down Expand Up @@ -242,6 +244,7 @@ const galleryMetaContainer = css`
export const ArticleMetaApps = ({
branding,
format,
layoutType,
byline,
tags,
primaryDateline,
Expand All @@ -255,7 +258,7 @@ export const ArticleMetaApps = ({
}: Props) => {
const soleContributor = getSoleContributor(tags, byline);
const authorName = soleContributor?.title ?? 'Author Image';
const avatarUrl = shouldShowAvatar(format)
const avatarUrl = shouldShowAvatar(format, layoutType)
? soleContributor?.bylineLargeImageUrl
: undefined;

Expand Down Expand Up @@ -328,7 +331,7 @@ export const ArticleMetaApps = ({
</MetaGridAvatar>
)}
<MetaGridByline isComment={isComment}>
{shouldShowContributor(format) && !!byline && (
{shouldShowContributor(format, layoutType) && !!byline && (
<Contributor
byline={byline}
tags={tags}
Expand Down
120 changes: 102 additions & 18 deletions dotcom-rendering/src/components/ArticleMeta.web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Hide } from '@guardian/source/react-components';
import { StraightLines } from '@guardian/source-development-kitchen/react-components';
import type { CSSProperties } from 'react';
import type { FEArticle } from '../frontend/feArticle';
import type { LayoutType } from '../layouts/lib/articleArrangements';
import { interactiveLegacyClasses } from '../layouts/lib/interactiveLegacyStyling';
import {
ArticleDesign,
Expand Down Expand Up @@ -43,6 +44,7 @@ import { TimeDateline } from './TimeDateline';

type Props = {
format: ArticleFormat;
layoutType?: LayoutType;
pageId: string;
webTitle: string;
byline?: string;
Expand Down Expand Up @@ -109,11 +111,7 @@ const metaFlex = css`
`;

const preferredSourceMetaFlex = (hasButton: boolean): CSSProperties =>
hasButton
? {
marginBottom: 8,
}
: {};
hasButton ? { marginBottom: 8 } : {};

const stretchLines = css`
display: block;
Expand Down Expand Up @@ -152,11 +150,7 @@ const metaExtras = (isPictureContent: boolean) => css`
`;

const preferredSourceMetaExtras = (hasButton: boolean): CSSProperties =>
hasButton
? {
paddingTop: 8,
}
: {};
hasButton ? { paddingTop: 8 } : {};

const metaNumbers = (isPictureContent: boolean) => css`
border-top: 1px solid ${themePalette('--article-border')};
Expand Down Expand Up @@ -249,6 +243,25 @@ const MetaAvatarContainer = ({ children }: { children: React.ReactNode }) => (
</div>
);

const ImmersiveMetaAvatarContainer = ({
children,
}: {
children: React.ReactNode;
}) => (
<div
css={css`
width: 60px;
height: 60px;
margin-top: 3px;
margin-right: 10px;
margin-bottom: 12px;
margin-left: 0px;
`}
>
{children}
</div>
);

const RowBelowLeftCol = ({ children }: { children: React.ReactNode }) => (
<div
css={css`
Expand Down Expand Up @@ -279,6 +292,7 @@ const metaNumbersExtrasLiveBlog = css`
export const ArticleMeta = ({
branding,
format,
layoutType,
pageId,
webTitle,
byline,
Expand All @@ -301,13 +315,21 @@ export const ArticleMeta = ({
const soleContributor = getSoleContributor(tags, byline);
const authorName = soleContributor?.title ?? 'Author Image';

const avatarUrl = shouldShowAvatar(format)
const avatarUrl = shouldShowAvatar(format, layoutType)
? soleContributor?.bylineLargeImageUrl
: undefined;
const isInteractive = format.design === ArticleDesign.Interactive;

const isPictureContent = format.design === ArticleDesign.Picture;

const isImmersive = format.display === ArticleDisplay.Immersive;

const isPortraitOrLandscapeImmersive =
layoutType === 'immersiveLandscapeDefault' ||
layoutType === 'immersivePortraitDefault' ||
layoutType === 'immersiveLandscapeFeature' ||
layoutType === 'immersivePortraitFeature';

const isAudio = format.design === ArticleDesign.Audio;

const seriesTag = getSeriesTag(tags);
Expand Down Expand Up @@ -350,12 +372,17 @@ export const ArticleMeta = ({
) : (
''
)}
<RowBelowLeftCol>
<>
{isImmersive && isPortraitOrLandscapeImmersive ? (
<div
css={css`
display: flex;
flex-direction: row;
`}
>
{!!avatarUrl && (
<MetaAvatarContainer>
<ImmersiveMetaAvatarContainer>
<Avatar src={avatarUrl} alt={authorName} />
</MetaAvatarContainer>
</ImmersiveMetaAvatarContainer>
)}
<div>
{isAudio && podcast && seriesTag && (
Expand All @@ -372,7 +399,7 @@ export const ArticleMeta = ({
/>
)}

{shouldShowContributor(format) && (
{shouldShowContributor(format, layoutType) && (
<Contributor
byline={byline}
tags={tags}
Expand Down Expand Up @@ -403,9 +430,66 @@ export const ArticleMeta = ({
/>
)}
</div>
</>
</RowBelowLeftCol>
</div>
) : (
<RowBelowLeftCol>
<>
{!!avatarUrl && (
<MetaAvatarContainer>
<Avatar src={avatarUrl} alt={authorName} />
</MetaAvatarContainer>
)}
<div>
{isAudio && podcast && seriesTag && (
<PodcastMeta
series={seriesTag}
format={format}
image={podcast.image}
spotifyUrl={podcast.spotifyUrl}
subscriptionUrl={
podcast.subscriptionUrl
}
audioDownloadUrl={
audioData?.audioDownloadUrl
}
rssFeedUrl={rssFeedUrl}
/>
)}

{shouldShowContributor(format, layoutType) && (
<Contributor
byline={byline}
tags={tags}
format={format}
source={source}
/>
)}

{crossword?.creator && (
<CrosswordSetter
setter={crossword.creator.name}
profileUrl={crossword.creator.webUrl}
/>
)}

{!isUndefined(webPublicationDate) &&
isFilterArticle ? (
<TimeDateline
primaryDateline={primaryDateline}
webPublicationDate={webPublicationDate}
format={format}
/>
) : (
<Dateline
primaryDateline={primaryDateline}
secondaryDateline={secondaryDateline}
format={format}
/>
)}
</div>
</>
</RowBelowLeftCol>
)}
<div
data-print-layout="hide"
css={metaFlex}
Expand Down
6 changes: 5 additions & 1 deletion dotcom-rendering/src/components/ArticleTitle.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { css } from '@emotion/react';
import { from } from '@guardian/source/foundations';
import { grid } from '../../src/grid';
import type { LayoutType } from '../layouts/lib/articleArrangements';
import {
ArticleDesign,
ArticleDisplay,
Expand All @@ -11,8 +12,9 @@ import { SeriesSectionLink } from './SeriesSectionLink';

type Props = {
format: ArticleFormat;
tags: TagType[];
layoutType?: LayoutType;
sectionLabel: string;
tags: TagType[];
sectionUrl: string;
guardianBaseURL: string;
isMatch?: boolean;
Expand Down Expand Up @@ -51,6 +53,7 @@ const galleryStyles = css`

export const ArticleTitle = ({
format,
layoutType,
tags,
sectionLabel,
sectionUrl,
Expand All @@ -74,6 +77,7 @@ export const ArticleTitle = ({
>
<SeriesSectionLink
format={format}
layoutType={layoutType}
tags={tags}
sectionLabel={sectionLabel}
sectionUrl={sectionUrl}
Expand Down
36 changes: 35 additions & 1 deletion dotcom-rendering/src/components/SeriesSectionLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
textSansBold20,
until,
} from '@guardian/source/foundations';
import type { LayoutType } from '../layouts/lib/articleArrangements';
import { interactiveLegacyClasses } from '../layouts/lib/interactiveLegacyStyling';
import {
ArticleDesign,
Expand All @@ -26,6 +27,7 @@ import { PulsingDot } from './PulsingDot.island';

type Props = {
format: ArticleFormat;
layoutType?: LayoutType;
tags: TagType[];
sectionLabel: string;
sectionUrl: string;
Expand Down Expand Up @@ -190,6 +192,7 @@ const sectionPadding = css`

export const SeriesSectionLink = ({
format,
layoutType,
tags,
sectionLabel,
sectionUrl,
Expand Down Expand Up @@ -376,7 +379,38 @@ export const SeriesSectionLink = ({
</div>
);
}
// Immersives show nothing at all if there's no series tag
if (
layoutType === 'immersivePortraitDefault' ||
layoutType === 'immersivePortraitFeature' ||
layoutType === 'immersiveLandscapeDefault' ||
layoutType === 'immersiveLandscapeFeature'
) {
return (
<>
<a
href={`${guardianBaseURL}/${sectionUrl}`}
css={[
sectionLabelLink,
css`
color: ${titleColour};
background-color: ${themePalette(
'--section-title-background',
)};
`,
marginRight,
fontStyles(format),
breakWord,
]}
data-component="section"
data-link-name="article section"
className={interactiveLegacyClasses.labelLink}
>
<span>{sectionLabel}</span>
</a>
</>
);
}
// Other types of immersives show nothing at all if there's no series tag
return null;
}
if (tag) {
Expand Down
Loading
Loading