1
1
import { css } from '@emotion/react' ;
2
- import { from , space } from '@guardian/source/foundations' ;
2
+ import { from , space , until } from '@guardian/source/foundations' ;
3
3
import { SvgMediaControlsPlay } from '@guardian/source/react-components' ;
4
4
import { ArticleDesign , type ArticleFormat } from '../lib/articleFormat' ;
5
5
import { secondsToDuration } from '../lib/formatTime' ;
@@ -107,9 +107,10 @@ const overlayContainerStyles = css`
107
107
108
108
const immersiveOverlayContainerStyles = css `
109
109
${ from . tablet } {
110
- height : 100% ;
111
110
top : 0 ;
112
- width : 25% ;
111
+ height : 100% ;
112
+ width : 220px ;
113
+ z-index : 1 ;
113
114
}
114
115
` ;
115
116
@@ -146,7 +147,7 @@ const overlayStyles = css`
146
147
${ overlayMaskGradientStyles ( '180deg' ) } ;
147
148
148
149
/* Ensure the waveform is behind the other elements, e.g. headline, pill */
149
- > * {
150
+ > : not (. waveform ) {
150
151
z-index : 1 ;
151
152
}
152
153
` ;
@@ -171,6 +172,20 @@ const podcastImageStyles = css`
171
172
width : 80px ;
172
173
` ;
173
174
175
+ const nonImmersivePodcastImageStyles = css `
176
+ position : absolute;
177
+ /**
178
+ * Displays 8px above the text.
179
+ * desired space above text (8px) - padding-top of text container (64px) = -56px
180
+ */
181
+ bottom : -${ space [ 14 ] } px;
182
+ left : ${ space [ 2 ] } px;
183
+
184
+ ${ from . tablet } {
185
+ display : none;
186
+ }
187
+ ` ;
188
+
174
189
const starRatingWrapper = css `
175
190
background-color : ${ palette ( '--star-rating-background' ) } ;
176
191
color : ${ palette ( '--star-rating-fill' ) } ;
@@ -353,7 +368,7 @@ export const FeatureCard = ({
353
368
isExternalLink = { isExternalLink }
354
369
/>
355
370
) }
356
- < div css = { [ contentStyles ] } >
371
+ < div css = { contentStyles } >
357
372
{ showYoutubeVideo && (
358
373
< div
359
374
data-chromatic = "ignore"
@@ -488,45 +503,45 @@ export const FeatureCard = ({
488
503
immersiveOverlayContainerStyles ,
489
504
] }
490
505
>
506
+ { mainMedia ?. type === 'Audio' &&
507
+ ! ! mainMedia . podcastImage ?. src && (
508
+ < div
509
+ css = {
510
+ podcastImageContainerStyles
511
+ }
512
+ >
513
+ < div
514
+ css = { [
515
+ podcastImageStyles ,
516
+ nonImmersivePodcastImageStyles ,
517
+ ] }
518
+ >
519
+ < CardPicture
520
+ mainImage = {
521
+ mainMedia
522
+ . podcastImage
523
+ . src
524
+ }
525
+ imageSize = "podcast"
526
+ alt = {
527
+ mainMedia
528
+ . podcastImage
529
+ . altText ?? ''
530
+ }
531
+ loading = "lazy"
532
+ roundedCorners = { false }
533
+ aspectRatio = "1:1"
534
+ />
535
+ </ div >
536
+ </ div >
537
+ ) }
491
538
< div
492
539
css = { [
493
540
overlayStyles ,
494
541
isImmersive &&
495
542
immersiveOverlayStyles ,
496
543
] }
497
544
>
498
- { mainMedia ?. type === 'Audio' &&
499
- ! ! mainMedia . podcastImage ?. src && (
500
- < div
501
- css = {
502
- podcastImageContainerStyles
503
- }
504
- >
505
- < div
506
- css = { podcastImageStyles }
507
- >
508
- < CardPicture
509
- mainImage = {
510
- mainMedia
511
- . podcastImage
512
- . src
513
- }
514
- imageSize = "podcast"
515
- alt = {
516
- mainMedia
517
- . podcastImage
518
- . altText ??
519
- ''
520
- }
521
- loading = "lazy"
522
- roundedCorners = {
523
- false
524
- }
525
- aspectRatio = "1:1"
526
- />
527
- </ div >
528
- </ div >
529
- ) }
530
545
{ /**
531
546
* Without the wrapping div the headline and byline would have space
532
547
* inserted between them due to being direct children of the flex container
@@ -585,17 +600,46 @@ export const FeatureCard = ({
585
600
</ div >
586
601
) }
587
602
588
- { mainMedia ?. type === 'Audio' && (
589
- < div css = { waveformStyles } >
590
- < WaveForm
591
- seed = { mainMedia . duration }
592
- height = { 64 }
593
- // Just enough to cover the full width of the feature card in it's largest form
594
- bars = { 233 }
595
- barWidth = { 2 }
596
- />
597
- </ div >
598
- ) }
603
+ { isImmersive &&
604
+ mainMedia ?. type === 'Audio' &&
605
+ ! ! mainMedia . podcastImage ?. src && (
606
+ < div
607
+ css = {
608
+ podcastImageContainerStyles
609
+ }
610
+ >
611
+ < div
612
+ css = { [
613
+ podcastImageStyles ,
614
+ css `
615
+ ${ until . tablet } {
616
+ display : none;
617
+ }
618
+ ` ,
619
+ ] }
620
+ >
621
+ < CardPicture
622
+ mainImage = {
623
+ mainMedia
624
+ . podcastImage
625
+ . src
626
+ }
627
+ imageSize = "podcast"
628
+ alt = {
629
+ mainMedia
630
+ . podcastImage
631
+ . altText ??
632
+ ''
633
+ }
634
+ loading = "lazy"
635
+ roundedCorners = {
636
+ false
637
+ }
638
+ aspectRatio = "1:1"
639
+ />
640
+ </ div >
641
+ </ div >
642
+ ) }
599
643
600
644
< CardFooter
601
645
format = { format }
@@ -644,6 +688,24 @@ export const FeatureCard = ({
644
688
mainMedia = { mainMedia }
645
689
isNewsletter = { isNewsletter }
646
690
/>
691
+
692
+ { ! isImmersive &&
693
+ mainMedia ?. type === 'Audio' && (
694
+ < div
695
+ css = { waveformStyles }
696
+ className = "waveform"
697
+ >
698
+ < WaveForm
699
+ seed = {
700
+ mainMedia . duration
701
+ }
702
+ height = { 64 }
703
+ // Just enough to cover the full width of the feature card in it's largest form
704
+ bars = { 233 }
705
+ barWidth = { 2 }
706
+ />
707
+ </ div >
708
+ ) }
647
709
</ div >
648
710
{ /* On video article cards, the duration is displayed in the footer */ }
649
711
{ ! isVideoArticle &&
@@ -663,6 +725,21 @@ export const FeatureCard = ({
663
725
</ div >
664
726
) : null }
665
727
</ div >
728
+
729
+ { isImmersive && mainMedia ?. type === 'Audio' && (
730
+ < div
731
+ css = { waveformStyles }
732
+ className = "waveform"
733
+ >
734
+ < WaveForm
735
+ seed = { mainMedia . duration }
736
+ height = { 64 }
737
+ // Just enough to cover the full width of the feature card in it's largest form
738
+ bars = { 314 }
739
+ barWidth = { 2 }
740
+ />
741
+ </ div >
742
+ ) }
666
743
</ div >
667
744
) }
668
745
</ div >
0 commit comments