Skip to content

Commit e2f5162

Browse files
Handle author/artist avatars
1 parent c2ecfb7 commit e2f5162

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;
@@ -182,6 +232,13 @@ export const StandardLayout = (props: WebProps | AppProps) => {
182232
? 'showcase'
183233
: 'standard';
184234

235+
const avatarUrl = getSoleContributor(
236+
article.tags,
237+
article.byline,
238+
)?.bylineLargeImageUrl;
239+
240+
const displayAvatarUrl = avatarUrl ? true : false;
241+
185242
return (
186243
<>
187244
{isWeb && (
@@ -276,7 +333,17 @@ export const StandardLayout = (props: WebProps | AppProps) => {
276333
`,
277334
]}
278335
>
279-
<GridItem area="media" layoutType={layoutType}>
336+
<GridItem
337+
area="media"
338+
layoutType={layoutType}
339+
css={
340+
displayAvatarUrl
341+
? css`
342+
margin-top: 8px;
343+
`
344+
: undefined
345+
}
346+
>
280347
<MainMedia
281348
format={format}
282349
elements={article.mainMediaElements}
@@ -301,6 +368,11 @@ export const StandardLayout = (props: WebProps | AppProps) => {
301368
area="title"
302369
layoutType={layoutType}
303370
element="aside"
371+
css={css`
372+
display: flex;
373+
flex-direction: column;
374+
justify-content: space-between;
375+
`}
304376
>
305377
<ArticleTitle
306378
format={format}
@@ -310,19 +382,70 @@ export const StandardLayout = (props: WebProps | AppProps) => {
310382
guardianBaseURL={article.guardianBaseURL}
311383
isMatch={!!footballMatchUrl}
312384
/>
385+
{displayAvatarUrl && (
386+
<Hide until="leftCol">
387+
<StraightLines
388+
count={8}
389+
cssOverrides={css`
390+
display: block;
391+
`}
392+
color={themePalette('--straight-lines')}
393+
/>
394+
</Hide>
395+
)}
313396
</GridItem>
314-
<GridItem area="headline" layoutType={layoutType}>
315-
<ArticleHeadline
316-
format={format}
317-
headlineString={article.headline}
318-
tags={article.tags}
319-
byline={article.byline}
320-
webPublicationDateDeprecated={
321-
article.webPublicationDateDeprecated
322-
}
323-
starRating={article.starRating}
324-
/>
325-
</GridItem>
397+
{displayAvatarUrl ? (
398+
<GridItem area="headline" layoutType={layoutType}>
399+
<div css={avatarHeadlineWrapper}>
400+
<ArticleHeadline
401+
format={format}
402+
headlineString={article.headline}
403+
tags={article.tags}
404+
byline={article.byline}
405+
webPublicationDateDeprecated={
406+
article.webPublicationDateDeprecated
407+
}
408+
hasAvatar={displayAvatarUrl}
409+
starRating={article.starRating}
410+
/>
411+
412+
<div>
413+
{!!avatarUrl && (
414+
<div css={avatarPositionStyles}>
415+
<ContributorAvatar
416+
imageSrc={avatarUrl}
417+
imageAlt={
418+
article.byline ?? ''
419+
}
420+
/>
421+
</div>
422+
)}
423+
<StraightLines
424+
count={8}
425+
cssOverrides={css`
426+
display: block;
427+
`}
428+
color={themePalette(
429+
'--straight-lines',
430+
)}
431+
/>
432+
</div>
433+
</div>
434+
</GridItem>
435+
) : (
436+
<GridItem area="headline" layoutType={layoutType}>
437+
<ArticleHeadline
438+
format={format}
439+
headlineString={article.headline}
440+
tags={article.tags}
441+
byline={article.byline}
442+
webPublicationDateDeprecated={
443+
article.webPublicationDateDeprecated
444+
}
445+
starRating={article.starRating}
446+
/>
447+
</GridItem>
448+
)}
326449
<GridItem area="standfirst" layoutType={layoutType}>
327450
<Standfirst
328451
format={format}
@@ -339,12 +462,12 @@ export const StandardLayout = (props: WebProps | AppProps) => {
339462
format.theme === ArticleSpecial.Labs &&
340463
format.design !== ArticleDesign.Video ? (
341464
<GuardianLabsLines />
342-
) : (
465+
) : !displayAvatarUrl ? (
343466
<DecideLines
344467
format={format}
345468
color={themePalette('--article-border')}
346469
/>
347-
)}
470+
) : null}
348471
</div>
349472
{isApps ? (
350473
<>

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)