Skip to content

Commit 53aad3f

Browse files
Handle author/artist avatars
1 parent 9b7a8b8 commit 53aad3f

3 files changed

Lines changed: 148 additions & 19 deletions

File tree

dotcom-rendering/src/components/ArticleHeadline.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -874,10 +874,15 @@ export const ArticleHeadline = ({
874874
case ArticleDesign.Picture:
875875
return (
876876
<div
877-
css={decideBottomPadding({
878-
format,
879-
hasAvatar,
880-
})}
877+
css={[
878+
decideBottomPadding({
879+
format,
880+
hasAvatar,
881+
}),
882+
css`
883+
max-width: 620px;
884+
`,
885+
]}
881886
>
882887
<DesignTag format={format} />
883888
<h1

dotcom-rendering/src/layouts/StandardLayout.tsx

Lines changed: 138 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { ArticleMetaApps } from '../components/ArticleMeta.apps';
2020
import { ArticleMeta } from '../components/ArticleMeta.web';
2121
import { ArticleTitle } from '../components/ArticleTitle';
2222
import { Carousel } from '../components/Carousel.island';
23+
import { ContributorAvatar } from '../components/ContributorAvatar';
2324
import { CricketMatchHeaderWrapper } from '../components/CricketMatchHeaderWrapper.island';
2425
import { DecideLines } from '../components/DecideLines';
2526
import { DirectoryPageNavIsland } from '../components/DirectoryPageNavIsland';
@@ -52,6 +53,7 @@ import {
5253
type ArticleFormat,
5354
ArticleSpecial,
5455
} from '../lib/articleFormat';
56+
import { getSoleContributor } from '../lib/byline';
5557
import { canRenderAds } from '../lib/canRenderAds';
5658
import { getContributionsServiceUrl } from '../lib/contributions';
5759
import { decideStoryPackageTrails } from '../lib/decideTrail';
@@ -81,6 +83,54 @@ const stretchLines = css`
8183
}
8284
`;
8385

86+
const avatarHeadlineWrapper = css`
87+
display: flex;
88+
flex-direction: column;
89+
justify-content: space-between;
90+
`;
91+
92+
// This styling taken from the similar approach in CommentLayout.tsx
93+
// If in mobile increase the margin top and margin right deficit
94+
const avatarPositionStyles = css`
95+
display: flex;
96+
justify-content: flex-end;
97+
position: relative;
98+
margin-bottom: -29px;
99+
pointer-events: none;
100+
${from.desktop} {
101+
margin-top: -50px;
102+
}
103+
${until.tablet} {
104+
overflow: hidden;
105+
}
106+
107+
/* Why target img element?
108+
109+
Because only in this context, where we have overflow: hidden
110+
and the margin-bottom and margin-top of avatarPositionStyles
111+
do we also want to apply our margin-right. These styles
112+
are tightly coupled in this context, and so it does not
113+
make sense to move them to the avatar component.
114+
115+
It's imperfect from the perspective of DCR, the alternative is to bust
116+
the combined elements into a separate component (with the
117+
relevant stories) and couple them that way, which might be what
118+
you want to do if you find yourself adding more styles
119+
to this section. For now, this works without making me 🤢.
120+
*/
121+
122+
${from.mobile} {
123+
img {
124+
margin-right: -1.85rem;
125+
}
126+
}
127+
${from.mobileLandscape} {
128+
img {
129+
margin-right: -1.25rem;
130+
}
131+
}
132+
`;
133+
84134
interface GridItemProps {
85135
area: Area;
86136
layoutType: LayoutType;
@@ -190,6 +240,13 @@ export const StandardLayout = (props: WebProps | AppProps) => {
190240
? 'showcase'
191241
: 'standard';
192242

243+
const avatarUrl = getSoleContributor(
244+
article.tags,
245+
article.byline,
246+
)?.bylineLargeImageUrl;
247+
248+
const displayAvatarUrl = avatarUrl ? true : false;
249+
193250
return (
194251
<>
195252
{isWeb && (
@@ -285,7 +342,17 @@ export const StandardLayout = (props: WebProps | AppProps) => {
285342
`,
286343
]}
287344
>
288-
<GridItem area="media" layoutType={layoutType}>
345+
<GridItem
346+
area="media"
347+
layoutType={layoutType}
348+
css={
349+
displayAvatarUrl
350+
? css`
351+
margin-top: 8px;
352+
`
353+
: undefined
354+
}
355+
>
289356
<MainMedia
290357
format={format}
291358
elements={article.mainMediaElements}
@@ -310,6 +377,11 @@ export const StandardLayout = (props: WebProps | AppProps) => {
310377
area="title"
311378
layoutType={layoutType}
312379
element="aside"
380+
css={css`
381+
display: flex;
382+
flex-direction: column;
383+
justify-content: space-between;
384+
`}
313385
>
314386
<ArticleTitle
315387
format={format}
@@ -319,19 +391,70 @@ export const StandardLayout = (props: WebProps | AppProps) => {
319391
guardianBaseURL={article.guardianBaseURL}
320392
isMatch={!!footballMatchUrl}
321393
/>
394+
{displayAvatarUrl && (
395+
<Hide until="leftCol">
396+
<StraightLines
397+
count={8}
398+
cssOverrides={css`
399+
display: block;
400+
`}
401+
color={themePalette('--straight-lines')}
402+
/>
403+
</Hide>
404+
)}
322405
</GridItem>
323-
<GridItem area="headline" layoutType={layoutType}>
324-
<ArticleHeadline
325-
format={format}
326-
headlineString={article.headline}
327-
tags={article.tags}
328-
byline={article.byline}
329-
webPublicationDateDeprecated={
330-
article.webPublicationDateDeprecated
331-
}
332-
starRating={article.starRating}
333-
/>
334-
</GridItem>
406+
{displayAvatarUrl ? (
407+
<GridItem area="headline" layoutType={layoutType}>
408+
<div css={avatarHeadlineWrapper}>
409+
<ArticleHeadline
410+
format={format}
411+
headlineString={article.headline}
412+
tags={article.tags}
413+
byline={article.byline}
414+
webPublicationDateDeprecated={
415+
article.webPublicationDateDeprecated
416+
}
417+
hasAvatar={displayAvatarUrl}
418+
starRating={article.starRating}
419+
/>
420+
421+
<div>
422+
{!!avatarUrl && (
423+
<div css={avatarPositionStyles}>
424+
<ContributorAvatar
425+
imageSrc={avatarUrl}
426+
imageAlt={
427+
article.byline ?? ''
428+
}
429+
/>
430+
</div>
431+
)}
432+
<StraightLines
433+
count={8}
434+
cssOverrides={css`
435+
display: block;
436+
`}
437+
color={themePalette(
438+
'--straight-lines',
439+
)}
440+
/>
441+
</div>
442+
</div>
443+
</GridItem>
444+
) : (
445+
<GridItem area="headline" layoutType={layoutType}>
446+
<ArticleHeadline
447+
format={format}
448+
headlineString={article.headline}
449+
tags={article.tags}
450+
byline={article.byline}
451+
webPublicationDateDeprecated={
452+
article.webPublicationDateDeprecated
453+
}
454+
starRating={article.starRating}
455+
/>
456+
</GridItem>
457+
)}
335458
<GridItem area="standfirst" layoutType={layoutType}>
336459
<Standfirst
337460
format={format}
@@ -348,12 +471,12 @@ export const StandardLayout = (props: WebProps | AppProps) => {
348471
format.theme === ArticleSpecial.Labs &&
349472
format.design !== ArticleDesign.Video ? (
350473
<GuardianLabsLines />
351-
) : (
474+
) : !displayAvatarUrl ? (
352475
<DecideLines
353476
format={format}
354477
color={themePalette('--article-border')}
355478
/>
356-
)}
479+
) : null}
357480
</div>
358481
{isApps ? (
359482
<>

dotcom-rendering/src/layouts/lib/articleArrangements.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ const pictureCss: LayoutCssMap = {
158158
headline: {
159159
mobile: 'grid-row: 2;',
160160
tablet: 'grid-row: 2;',
161+
desktop: `grid-row: 2; ${grid.between('centre-column-start', 'right-column-end')};`,
161162
leftCol: 'grid-row: 1;',
162163
},
163164
standfirst: {

0 commit comments

Comments
 (0)