Skip to content

Commit 268a8da

Browse files
committed
add gallery lightbox
1 parent 52278ca commit 268a8da

File tree

3 files changed

+70
-48
lines changed

3 files changed

+70
-48
lines changed

dotcom-rendering/src/components/GalleryImage.tsx

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11
import { css } from '@emotion/react';
2+
import { isUndefined } from '@guardian/libs';
23
import { from, space, until } from '@guardian/source/foundations';
34
import { grid } from '../grid';
45
import { type ArticleFormat } from '../lib/articleFormat';
56
import { getImage } from '../lib/image';
67
import { palette } from '../palette';
78
import { type ImageBlockElement } from '../types/content';
9+
import { type RenderingTarget } from '../types/renderingTarget';
810
import { GalleryCaption } from './GalleryCaption';
11+
import { LightboxLink } from './LightboxLink';
912
import { Picture } from './Picture';
1013

1114
type Props = {
1215
format: ArticleFormat;
1316
image: ImageBlockElement;
1417
pageId: string;
1518
webTitle: string;
19+
renderingTarget: RenderingTarget;
1620
};
1721

1822
const styles = css`
@@ -31,7 +35,30 @@ const styles = css`
3135
}
3236
`;
3337

34-
export const GalleryImage = ({ format, image, pageId, webTitle }: Props) => {
38+
const galleryBodyImageStyles = css`
39+
display: flex;
40+
${grid.column.all}
41+
42+
${from.tablet} {
43+
${grid.column.centre}
44+
}
45+
46+
${from.desktop} {
47+
padding-bottom: ${space[10]}px;
48+
}
49+
50+
${from.leftCol} {
51+
${grid.between('centre-column-start', 'right-column-end')}
52+
}
53+
`;
54+
55+
export const GalleryImage = ({
56+
format,
57+
image,
58+
pageId,
59+
webTitle,
60+
renderingTarget,
61+
}: Props) => {
3562
const asset = getImage(image.media.allImages);
3663

3764
if (asset === undefined) {
@@ -47,15 +74,34 @@ export const GalleryImage = ({ format, image, pageId, webTitle }: Props) => {
4774

4875
return (
4976
<figure css={styles}>
50-
<Picture
51-
alt={image.data.alt ?? ''}
52-
format={format}
53-
role={image.role}
54-
master={asset.url}
55-
width={width}
56-
height={height}
57-
loading="lazy"
58-
/>
77+
<span css={galleryBodyImageStyles}>
78+
<span
79+
css={css`
80+
position: relative;
81+
`}
82+
>
83+
<Picture
84+
alt={image.data.alt ?? ''}
85+
format={format}
86+
role={image.role}
87+
master={asset.url}
88+
width={width}
89+
height={height}
90+
loading="lazy"
91+
/>
92+
{renderingTarget === 'Web' &&
93+
!isUndefined(image.position) && (
94+
<LightboxLink
95+
role={image.role}
96+
format={format}
97+
elementId={image.elementId}
98+
isMainMedia={false}
99+
position={image.position}
100+
/>
101+
)}
102+
</span>
103+
</span>
104+
59105
<GalleryCaption
60106
captionHtml={image.data.caption}
61107
credit={image.data.credit}

dotcom-rendering/src/components/Picture.tsx

Lines changed: 13 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import { css } from '@emotion/react';
2-
import { breakpoints, from, space } from '@guardian/source/foundations';
2+
import { breakpoints } from '@guardian/source/foundations';
33
import {
44
type CSSProperties,
55
Fragment,
66
useCallback,
77
useEffect,
88
useState,
99
} from 'react';
10-
import { grid } from '../grid';
1110
import {
1211
ArticleDesign,
1312
ArticleDisplay,
@@ -472,50 +471,28 @@ export const Sources = ({ sources }: { sources: ImageSource[] }) => {
472471
);
473472
};
474473

475-
const galleryBodyImageStyles = css`
476-
${grid.column.all}
477-
478-
${from.tablet} {
479-
${grid.column.centre}
480-
}
481-
482-
${from.desktop} {
483-
padding-bottom: ${space[10]}px;
484-
}
485-
486-
${from.leftCol} {
487-
${grid.between('centre-column-start', 'right-column-end')}
488-
}
489-
`;
490-
491474
/**
492475
* This ensures that the image height never goes above 96vh.
493476
* The ratio parameter should be width:height.
494477
*/
495478
const imageMaxWidth = (
496479
design: ArticleDesign,
497480
ratio: number,
481+
isMainMedia: boolean,
498482
): CSSProperties | undefined =>
499-
design === ArticleDesign.Gallery
483+
design === ArticleDesign.Gallery && !isMainMedia
500484
? { maxWidth: `calc(${ratio} * 96vh)` }
501485
: undefined;
502486

503-
const styles = (
504-
{ design }: ArticleFormat,
505-
isLightbox: boolean,
506-
isMainMedia: boolean,
507-
) => {
487+
const styles = ({ design }: ArticleFormat, isLightbox: boolean) => {
508488
if (design === ArticleDesign.Gallery) {
509-
return css(
510-
css`
511-
img {
512-
width: 100%;
513-
height: 100%;
514-
object-fit: cover;
515-
}
516-
`,
517-
isMainMedia ? undefined : galleryBodyImageStyles,
518-
);
489+
return css(css`
490+
img {
491+
width: 100%;
492+
height: 100%;
493+
object-fit: cover;
494+
}
495+
`);
519496
}
520497
return isLightbox ? flex : block;
521498
};
@@ -581,10 +558,7 @@ export const Picture = ({
581558
const fallbackSource = getFallbackSource(sources);
582559

583560
return (
584-
<picture
585-
css={styles(format, isLightbox, isMainMedia)}
586-
style={imageMaxWidth(format.design, 1 / ratio)}
587-
>
561+
<picture css={styles(format, isLightbox)}>
588562
{/* Immersive Main Media images get additional sources specifically for when in portrait orientation */}
589563
{format.display === ArticleDisplay.Immersive && isMainMedia && (
590564
<>
@@ -621,6 +595,7 @@ export const Picture = ({
621595
height={fallbackSource.width * ratio}
622596
loading={Picture.disableLazyLoading ? undefined : loading}
623597
css={isLightbox ? flex : block}
598+
style={imageMaxWidth(format.design, 1 / ratio, isMainMedia)}
624599
/>
625600
</picture>
626601
);

dotcom-rendering/src/layouts/GalleryLayout.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ export const GalleryLayout = (props: WebProps | AppProps) => {
179179
pageId={frontendData.pageId}
180180
webTitle={frontendData.webTitle}
181181
key={idx}
182+
renderingTarget={props.renderingTarget}
182183
/>
183184
))}
184185
<SubMeta

0 commit comments

Comments
 (0)