@financial-times/cp-content-pipeline-ui 6.14.0 → 6.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/lib/components/ArticleBody/index.d.ts +2 -1
- package/lib/components/ArticleBody/index.js +2 -2
- package/lib/components/ArticleBody/index.js.map +1 -1
- package/lib/components/ArticleInfo/index.d.ts +3 -3
- package/lib/components/ArticleInfo/index.js +2 -2
- package/lib/components/ArticleInfo/index.js.map +1 -1
- package/lib/components/BackToTopButton/client/index.d.ts +4 -2
- package/lib/components/BackToTopButton/client/index.js +2 -11
- package/lib/components/BackToTopButton/client/index.js.map +1 -1
- package/lib/components/BackToTopButton/client/utils.js +1 -2
- package/lib/components/BackToTopButton/client/utils.js.map +1 -1
- package/lib/components/BigNumber/index.d.ts +2 -1
- package/lib/components/BigNumber/index.js +2 -2
- package/lib/components/BigNumber/index.js.map +1 -1
- package/lib/components/Body/index.d.ts +2 -1
- package/lib/components/Body/index.js +2 -2
- package/lib/components/Body/index.js.map +1 -1
- package/lib/components/Byline/index.d.ts +2 -2
- package/lib/components/Byline/index.js +2 -2
- package/lib/components/Byline/index.js.map +1 -1
- package/lib/components/Clip/client/index.js.map +1 -1
- package/lib/components/Clip/client/progressBar.js.map +1 -1
- package/lib/components/Clip/client/utils.js +4 -5
- package/lib/components/Clip/client/utils.js.map +1 -1
- package/lib/components/Clip/components/Caption.d.ts +1 -1
- package/lib/components/Clip/components/Caption.js.map +1 -1
- package/lib/components/Clip/components/ClipTag.d.ts +1 -1
- package/lib/components/Clip/components/ClipTag.js.map +1 -1
- package/lib/components/Clip/components/ClosedCaptions.d.ts +2 -2
- package/lib/components/Clip/components/ClosedCaptions.js +1 -1
- package/lib/components/Clip/components/ClosedCaptions.js.map +1 -1
- package/lib/components/Clip/components/Container.d.ts +2 -3
- package/lib/components/Clip/components/Container.js +1 -1
- package/lib/components/Clip/components/Container.js.map +1 -1
- package/lib/components/Clip/components/ContentLayout.d.ts +2 -3
- package/lib/components/Clip/components/ContentLayout.js.map +1 -1
- package/lib/components/Clip/components/Credit.d.ts +1 -1
- package/lib/components/Clip/components/Credit.js.map +1 -1
- package/lib/components/Clip/components/VideoDescription.d.ts +1 -1
- package/lib/components/Clip/components/VideoDescription.js.map +1 -1
- package/lib/components/Clip/components/VideoInfoBox.d.ts +1 -1
- package/lib/components/Clip/components/VideoInfoBox.js.map +1 -1
- package/lib/components/Clip/template/component.d.ts +2 -2
- package/lib/components/Clip/template/component.js +2 -2
- package/lib/components/Clip/template/component.js.map +1 -1
- package/lib/components/Clip/template/index.js +1 -1
- package/lib/components/Clip/template/index.js.map +1 -1
- package/lib/components/Clip/test/fixtures.js.map +1 -1
- package/lib/components/Clip/test/index.spec.js.map +1 -1
- package/lib/components/Clip/test/snapshot.spec.js +2 -2
- package/lib/components/Clip/test/snapshot.spec.js.map +1 -1
- package/lib/components/ContentPackageBody/index.d.ts +2 -2
- package/lib/components/ContentPackageBody/index.js +9 -9
- package/lib/components/ContentPackageBody/index.js.map +1 -1
- package/lib/components/Expander/client/index.js.map +1 -1
- package/lib/components/Expander/test/client/index.spec.js.map +1 -1
- package/lib/components/FixedAspectRatio/FixedAspectRatio.d.ts +3 -1622
- package/lib/components/FixedAspectRatio/FixedAspectRatio.js +3 -3
- package/lib/components/FixedAspectRatio/FixedAspectRatio.js.map +1 -1
- package/lib/components/Flourish/client/index.js.map +1 -1
- package/lib/components/Flourish/index.d.ts +2 -2
- package/lib/components/Flourish/index.js +2 -2
- package/lib/components/Flourish/index.js.map +1 -1
- package/lib/components/Heading/index.d.ts +2 -5
- package/lib/components/Heading/index.js +2 -1
- package/lib/components/Heading/index.js.map +1 -1
- package/lib/components/Headshot/index.d.ts +2 -2
- package/lib/components/Headshot/index.js +2 -2
- package/lib/components/Headshot/index.js.map +1 -1
- package/lib/components/ImageSet/index.d.ts +8 -6
- package/lib/components/ImageSet/index.js +11 -11
- package/lib/components/ImageSet/index.js.map +1 -1
- package/lib/components/Layout/index.d.ts +4 -10
- package/lib/components/Layout/index.js +7 -7
- package/lib/components/Layout/index.js.map +1 -1
- package/lib/components/LiveBlogBody/index.d.ts +2 -2
- package/lib/components/LiveBlogBody/index.js +2 -2
- package/lib/components/LiveBlogBody/index.js.map +1 -1
- package/lib/components/LiveBlogPost/ShareButtons.d.ts +4 -3
- package/lib/components/LiveBlogPost/ShareButtons.js +2 -1
- package/lib/components/LiveBlogPost/ShareButtons.js.map +1 -1
- package/lib/components/LiveBlogPost/Timestamp.d.ts +2 -2
- package/lib/components/LiveBlogPost/Timestamp.js +2 -1
- package/lib/components/LiveBlogPost/Timestamp.js.map +1 -1
- package/lib/components/LiveBlogPost/index.d.ts +1 -1
- package/lib/components/LiveBlogPost/index.js +1 -1
- package/lib/components/LiveBlogPost/index.js.map +1 -1
- package/lib/components/LiveBlogPost/svgIcons.d.ts +3 -3
- package/lib/components/LiveBlogPost/svgIcons.js +6 -6
- package/lib/components/LiveBlogPost/svgIcons.js.map +1 -1
- package/lib/components/LiveBlogWrapper/dispatchEvent.js.map +1 -1
- package/lib/components/LiveBlogWrapper/index.js.map +1 -1
- package/lib/components/LiveBlogWrapper/normalisePost.js.map +1 -1
- package/lib/components/LiveBlogWrapper/post-tracker.js +2 -2
- package/lib/components/LiveBlogWrapper/post-tracker.js.map +1 -1
- package/lib/components/MainImage/index.d.ts +2 -2
- package/lib/components/MainImage/index.js +2 -2
- package/lib/components/MainImage/index.js.map +1 -1
- package/lib/components/Paragraph/index.d.ts +2 -1
- package/lib/components/Paragraph/index.js +3 -3
- package/lib/components/Paragraph/index.js.map +1 -1
- package/lib/components/PodcastBody/index.d.ts +4 -2
- package/lib/components/PodcastBody/index.js +2 -2
- package/lib/components/PodcastBody/index.js.map +1 -1
- package/lib/components/Pullquote/index.d.ts +2 -2
- package/lib/components/Pullquote/index.js +2 -1
- package/lib/components/Pullquote/index.js.map +1 -1
- package/lib/components/Recommended/index.d.ts +2 -1
- package/lib/components/Recommended/index.js +2 -2
- package/lib/components/Recommended/index.js.map +1 -1
- package/lib/components/RichText/BasicComponents.d.ts +13 -13
- package/lib/components/RichText/BasicComponents.js +2 -2
- package/lib/components/RichText/BasicComponents.js.map +1 -1
- package/lib/components/RichText/index.d.ts +3 -3
- package/lib/components/RichText/index.js +2 -2
- package/lib/components/RichText/index.js.map +1 -1
- package/lib/components/RichText/index.test.js +6 -6
- package/lib/components/RichText/index.test.js.map +1 -1
- package/lib/components/Scrollytelling/ScrollyImage.d.ts +1 -1
- package/lib/components/Scrollytelling/ScrollyImage.js +2 -2
- package/lib/components/Scrollytelling/ScrollyImage.js.map +1 -1
- package/lib/components/Scrollytelling/index.d.ts +5 -5
- package/lib/components/Scrollytelling/index.js +1 -1
- package/lib/components/Scrollytelling/index.js.map +1 -1
- package/lib/components/Table/TableBody.d.ts +2 -1
- package/lib/components/Table/TableBody.js +2 -2
- package/lib/components/Table/TableBody.js.map +1 -1
- package/lib/components/Table/TableCell.d.ts +4 -2
- package/lib/components/Table/TableCell.js.map +1 -1
- package/lib/components/Table/index.d.ts +2 -1
- package/lib/components/Table/index.js +2 -2
- package/lib/components/Table/index.js.map +1 -1
- package/lib/components/Topper/Columnist.d.ts +2 -2
- package/lib/components/Topper/Columnist.js +2 -2
- package/lib/components/Topper/Columnist.js.map +1 -1
- package/lib/components/Topper/FollowButtonSlot.d.ts +0 -1
- package/lib/components/Topper/Headline.d.ts +2 -2
- package/lib/components/Topper/Headline.js +2 -2
- package/lib/components/Topper/Headline.js.map +1 -1
- package/lib/components/Topper/Intro.d.ts +2 -1
- package/lib/components/Topper/Intro.js +2 -2
- package/lib/components/Topper/Intro.js.map +1 -1
- package/lib/components/Topper/LiveBlogIndicator.d.ts +2 -2
- package/lib/components/Topper/LiveBlogIndicator.js +2 -2
- package/lib/components/Topper/LiveBlogIndicator.js.map +1 -1
- package/lib/components/Topper/Picture.d.ts +2 -2
- package/lib/components/Topper/Picture.js +2 -2
- package/lib/components/Topper/Picture.js.map +1 -1
- package/lib/components/Topper/Tags.d.ts +2 -2
- package/lib/components/Topper/Tags.js +7 -7
- package/lib/components/Topper/Tags.js.map +1 -1
- package/lib/components/Topper/Wrapper.d.ts +3 -4
- package/lib/components/Topper/Wrapper.js +2 -2
- package/lib/components/Topper/Wrapper.js.map +1 -1
- package/lib/components/Topper/client/tracking.js.map +1 -1
- package/lib/components/Topper/index.d.ts +2 -1
- package/lib/components/Topper/index.js +2 -2
- package/lib/components/Topper/index.js.map +1 -1
- package/lib/components/Tweet/index.d.ts +2 -1
- package/lib/components/Tweet/index.js +2 -2
- package/lib/components/Tweet/index.js.map +1 -1
- package/lib/components/Video/index.d.ts +2 -1
- package/lib/components/Video/index.js +2 -2
- package/lib/components/Video/index.js.map +1 -1
- package/lib/components/YoutubeVideo/index.d.ts +2 -1
- package/lib/components/YoutubeVideo/index.js +2 -2
- package/lib/components/YoutubeVideo/index.js.map +1 -1
- package/lib/context.d.ts +0 -1
- package/lib/extensions/scrollIntoView.js +1 -1
- package/lib/extensions/scrollIntoView.js.map +1 -1
- package/lib/stories/BackToTop.stories.d.ts +5 -2
- package/lib/stories/BackToTop.stories.js.map +1 -1
- package/lib/stories/Clip.stories.d.ts +1 -2
- package/lib/stories/Clip.stories.js +1 -1
- package/lib/stories/Clip.stories.js.map +1 -1
- package/lib/stories/Expander.stories.d.ts +37 -25
- package/lib/stories/Expander.stories.js +207 -36
- package/lib/stories/Expander.stories.js.map +1 -1
- package/lib/stories/LiveBlogPost.stories.d.ts +1 -1
- package/lib/stories/LiveBlogPost.stories.js +6 -6
- package/lib/stories/LiveBlogPost.stories.js.map +1 -1
- package/lib/stories/Topper.stories.d.ts +2 -2
- package/package.json +2 -2
- package/src/components/ArticleBody/index.tsx +3 -4
- package/src/components/ArticleInfo/index.tsx +5 -3
- package/src/components/BackToTopButton/client/index.tsx +11 -6
- package/src/components/BigNumber/index.tsx +6 -9
- package/src/components/Body/index.tsx +4 -2
- package/src/components/Byline/index.tsx +3 -4
- package/src/components/Clip/components/Caption.tsx +1 -1
- package/src/components/Clip/components/ClipTag.tsx +2 -2
- package/src/components/Clip/components/ClosedCaptions.tsx +4 -2
- package/src/components/Clip/components/Container.tsx +5 -3
- package/src/components/Clip/components/ContentLayout.tsx +4 -3
- package/src/components/Clip/components/Credit.tsx +1 -1
- package/src/components/Clip/components/VideoDescription.tsx +2 -2
- package/src/components/Clip/components/VideoInfoBox.tsx +1 -1
- package/src/components/Clip/template/component.tsx +4 -2
- package/src/components/ContentPackageBody/index.tsx +9 -7
- package/src/components/Expander/client/main.scss +27 -17
- package/src/components/FixedAspectRatio/FixedAspectRatio.tsx +6 -5
- package/src/components/Flourish/index.tsx +4 -2
- package/src/components/Heading/index.tsx +5 -2
- package/src/components/Headshot/index.tsx +4 -2
- package/src/components/ImageSet/index.tsx +25 -21
- package/src/components/Layout/index.tsx +8 -15
- package/src/components/LiveBlogBody/index.tsx +4 -2
- package/src/components/LiveBlogPost/ShareButtons.tsx +10 -5
- package/src/components/LiveBlogPost/Timestamp.tsx +6 -1
- package/src/components/LiveBlogPost/index.tsx +6 -4
- package/src/components/LiveBlogPost/svgIcons.tsx +3 -3
- package/src/components/MainImage/index.tsx +3 -1
- package/src/components/Paragraph/index.tsx +5 -3
- package/src/components/PodcastBody/index.tsx +9 -2
- package/src/components/Pullquote/index.tsx +5 -3
- package/src/components/Recommended/index.tsx +5 -2
- package/src/components/RichText/BasicComponents.tsx +35 -30
- package/src/components/RichText/index.test.tsx +14 -13
- package/src/components/RichText/index.tsx +12 -8
- package/src/components/Scrollytelling/ScrollyImage.tsx +4 -4
- package/src/components/Scrollytelling/index.tsx +10 -10
- package/src/components/Table/TableBody.tsx +5 -3
- package/src/components/Table/TableCell.tsx +3 -3
- package/src/components/Table/index.tsx +6 -2
- package/src/components/Topper/Columnist.tsx +4 -2
- package/src/components/Topper/Headline.tsx +4 -2
- package/src/components/Topper/Intro.tsx +3 -1
- package/src/components/Topper/LiveBlogIndicator.tsx +4 -2
- package/src/components/Topper/Picture.tsx +8 -6
- package/src/components/Topper/Tags.tsx +6 -4
- package/src/components/Topper/Wrapper.tsx +5 -4
- package/src/components/Topper/index.tsx +4 -2
- package/src/components/Tweet/index.tsx +3 -1
- package/src/components/Video/index.tsx +4 -2
- package/src/components/YoutubeVideo/index.tsx +4 -2
- package/src/stories/Clip.stories.tsx +2 -6
- package/src/stories/Expander.stories.tsx +231 -51
- package/src/stories/article-page.scss +21 -1
- package/src/stories/tsconfig.json +7 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -32,7 +32,7 @@ interface ClipTagProps {
|
|
|
32
32
|
preload?: string
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
export const ClipTag = ({
|
|
35
|
+
export const ClipTag: React.FC<ClipTagProps> = ({
|
|
36
36
|
id,
|
|
37
37
|
dataLayout,
|
|
38
38
|
description,
|
|
@@ -50,7 +50,7 @@ export const ClipTag = ({
|
|
|
50
50
|
noInfoBox = false,
|
|
51
51
|
noCaption = false,
|
|
52
52
|
dataTrackable,
|
|
53
|
-
}
|
|
53
|
+
}) => {
|
|
54
54
|
const { pixelWidth, pixelHeight } = clip?.dataSource?.[0]
|
|
55
55
|
? clip.dataSource[0]
|
|
56
56
|
: { pixelWidth: 0, pixelHeight: 0 }
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { Accessibility } from '@financial-times/cp-content-pipeline-client'
|
|
3
3
|
|
|
4
|
-
interface
|
|
4
|
+
interface ClosedCaptionsProps {
|
|
5
5
|
accessibility?: Accessibility
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
export const ClosedCaptions = ({
|
|
8
|
+
export const ClosedCaptions: React.FC<ClosedCaptionsProps> = ({
|
|
9
|
+
accessibility,
|
|
10
|
+
}) => {
|
|
9
11
|
if (!accessibility?.captions?.[0]?.url) return <></>
|
|
10
12
|
|
|
11
13
|
return (
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react'
|
|
2
2
|
|
|
3
3
|
interface ContainerProps {
|
|
4
|
-
children: ReactNode
|
|
5
4
|
dataLayout: string
|
|
6
5
|
}
|
|
7
6
|
|
|
8
|
-
export const Container
|
|
7
|
+
export const Container: React.FC<React.PropsWithChildren<ContainerProps>> = ({
|
|
8
|
+
dataLayout,
|
|
9
|
+
children,
|
|
10
|
+
}) => {
|
|
9
11
|
return dataLayout === 'full-grid' ? (
|
|
10
12
|
<div className="n-content-layout__container" data-component="clip-set">
|
|
11
13
|
{children}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react'
|
|
2
2
|
|
|
3
3
|
interface ContentLayoutProps {
|
|
4
4
|
dataLayout: string
|
|
5
|
-
children: ReactNode
|
|
6
5
|
}
|
|
7
6
|
|
|
8
7
|
// data-layout-width='full-grid' prevent clashes with ads and share bar
|
|
9
|
-
export const ContentLayout
|
|
8
|
+
export const ContentLayout: React.FC<
|
|
9
|
+
React.PropsWithChildren<ContentLayoutProps>
|
|
10
|
+
> = ({ dataLayout, children }) => {
|
|
10
11
|
return dataLayout !== 'in-line' ? (
|
|
11
12
|
<div className="n-content-layout" data-layout-width="full-grid">
|
|
12
13
|
{children}
|
|
@@ -14,10 +14,10 @@ const renderTranscript = (transcript: RichText) => {
|
|
|
14
14
|
return <RichTextComponent structuredContent={transcript.structured} />
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
export const VideoDescription = ({
|
|
17
|
+
export const VideoDescription: React.FC<VideoDescriptionProps> = ({
|
|
18
18
|
description,
|
|
19
19
|
accessibility,
|
|
20
|
-
}
|
|
20
|
+
}) => {
|
|
21
21
|
if (!accessibility?.transcript && !description) return <></>
|
|
22
22
|
|
|
23
23
|
const title = `Video ${description ? 'description' : 'transcript'}`
|
|
@@ -26,7 +26,7 @@ export interface ClipProps {
|
|
|
26
26
|
preload?: string
|
|
27
27
|
preset?: Preset
|
|
28
28
|
}
|
|
29
|
-
|
|
29
|
+
const ClipComponent: React.FC<ClipProps> = ({
|
|
30
30
|
url,
|
|
31
31
|
id,
|
|
32
32
|
autoplay = false,
|
|
@@ -42,7 +42,7 @@ export default function ClipComponent({
|
|
|
42
42
|
accessibility = {},
|
|
43
43
|
preset = 'full-player',
|
|
44
44
|
preload = 'auto',
|
|
45
|
-
}
|
|
45
|
+
}) => {
|
|
46
46
|
// We support currently a single clip, with multiple sources.
|
|
47
47
|
let clip = {} as Clip
|
|
48
48
|
// V2 has an array of clips
|
|
@@ -109,3 +109,5 @@ export default function ClipComponent({
|
|
|
109
109
|
</ContentLayout>
|
|
110
110
|
)
|
|
111
111
|
}
|
|
112
|
+
|
|
113
|
+
export default ClipComponent
|
|
@@ -37,11 +37,11 @@ type ContentPackageBodyProps = BodyProps & {
|
|
|
37
37
|
AdSlot?: React.FC
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
const ContentPackageBody: React.FC<ContentPackageBodyProps> = ({
|
|
41
41
|
content,
|
|
42
42
|
richTextComponents,
|
|
43
43
|
AdSlot,
|
|
44
|
-
}
|
|
44
|
+
}) => {
|
|
45
45
|
if (content.__typename !== 'ContentPackage') {
|
|
46
46
|
return null
|
|
47
47
|
}
|
|
@@ -88,13 +88,13 @@ export default function ContentPackageBody({
|
|
|
88
88
|
)
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
const PackageTeasers: React.FC<PackageTeasersProps> = ({
|
|
92
92
|
primaryTeasers,
|
|
93
93
|
secondaryTeasers,
|
|
94
94
|
secondaryTeaserTitle,
|
|
95
95
|
secondaryTeaserMods,
|
|
96
96
|
AdSlot,
|
|
97
|
-
}
|
|
97
|
+
}) => {
|
|
98
98
|
return (
|
|
99
99
|
<div
|
|
100
100
|
className={classnames('package-container', {
|
|
@@ -117,7 +117,7 @@ function PackageTeasers({
|
|
|
117
117
|
)
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
|
|
120
|
+
const PrimaryTeasers: React.FC<PrimaryTeasersProps> = ({ teasers }) => {
|
|
121
121
|
return (
|
|
122
122
|
<div className="package-contents package-teasers--large">
|
|
123
123
|
<ul className="package-contents package-teasers__list">
|
|
@@ -145,11 +145,11 @@ function PrimaryTeasers({ teasers }: PrimaryTeasersProps) {
|
|
|
145
145
|
)
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
|
|
148
|
+
const SecondaryTeasers: React.FC<SecondaryTeasersProps> = ({
|
|
149
149
|
teaserTitle,
|
|
150
150
|
teasers,
|
|
151
151
|
teaserMods,
|
|
152
|
-
}
|
|
152
|
+
}) => {
|
|
153
153
|
return (
|
|
154
154
|
<div className="o-teaser-collection package-more">
|
|
155
155
|
{teaserTitle && (
|
|
@@ -172,3 +172,5 @@ function SecondaryTeasers({
|
|
|
172
172
|
</div>
|
|
173
173
|
)
|
|
174
174
|
}
|
|
175
|
+
|
|
176
|
+
export default ContentPackageBody
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
@import '@financial-times/o-grid/main';
|
|
4
4
|
@import '@financial-times/o-spacing/main';
|
|
5
5
|
|
|
6
|
-
$numberIntroductoryElements: 1;
|
|
7
6
|
$dataComponentVisibleElements: (
|
|
8
7
|
'clip-set',
|
|
9
8
|
'recommended',
|
|
@@ -23,28 +22,30 @@ $alwaysVisibleComponentSelectors: ();
|
|
|
23
22
|
}
|
|
24
23
|
@mixin AlwaysVisibleElements {
|
|
25
24
|
@each $component in $alwaysVisibleComponentSelectors {
|
|
26
|
-
#{$component} {
|
|
25
|
+
& > p:first-of-type ~ #{$component} {
|
|
27
26
|
display: block;
|
|
28
27
|
}
|
|
29
28
|
}
|
|
30
29
|
}
|
|
31
|
-
@mixin
|
|
32
|
-
& >
|
|
33
|
-
display: block;
|
|
30
|
+
@mixin OrderElements {
|
|
31
|
+
& > * {
|
|
34
32
|
order:1
|
|
35
33
|
}
|
|
36
|
-
& > :
|
|
34
|
+
& > p:first-of-type ~ * {
|
|
37
35
|
order:3
|
|
38
36
|
}
|
|
37
|
+
& > p:first-of-type ~ .cp-expander__expand {
|
|
38
|
+
order:2
|
|
39
|
+
}
|
|
39
40
|
}
|
|
40
41
|
@mixin expandeAndCollapse {
|
|
41
42
|
&[data-state='expanded'] {
|
|
42
43
|
.cp-expander-content {
|
|
43
44
|
// Show all the hidden children...
|
|
44
|
-
& >
|
|
45
|
+
& > *:not(.cp-expander__expand) {
|
|
45
46
|
display: block;
|
|
46
47
|
}
|
|
47
|
-
> .cp-expander__expand {
|
|
48
|
+
& > .cp-expander__expand {
|
|
48
49
|
display: none;
|
|
49
50
|
}
|
|
50
51
|
}
|
|
@@ -56,19 +57,27 @@ $alwaysVisibleComponentSelectors: ();
|
|
|
56
57
|
.cp-expander-content {
|
|
57
58
|
// Hide everything that comes after the expander...
|
|
58
59
|
// ... except the always visible children
|
|
59
|
-
|
|
60
|
+
> p:first-of-type ~ * {
|
|
60
61
|
display: none;
|
|
61
62
|
}
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
//when target truncated post show everything
|
|
64
|
+
&:target > p:first-of-type {
|
|
65
|
+
~ * {
|
|
66
|
+
display: block;
|
|
67
|
+
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
~ .cp-expander__expand {
|
|
71
|
+
display: none;
|
|
72
|
+
}
|
|
64
73
|
}
|
|
74
|
+
|
|
65
75
|
//show expand only when there is a p element, in this case we supose all other elements are exclusions that will be shown always
|
|
66
|
-
> p ~ .cp-expander__expand {
|
|
76
|
+
> p:first-of-type ~ .cp-expander__expand {
|
|
67
77
|
display: block;
|
|
68
|
-
order: 2;
|
|
69
78
|
}
|
|
70
|
-
|
|
71
|
-
> :
|
|
79
|
+
|
|
80
|
+
> p:first-of-type + .cp-expander__expand {
|
|
72
81
|
display: none;
|
|
73
82
|
}
|
|
74
83
|
|
|
@@ -76,9 +85,10 @@ $alwaysVisibleComponentSelectors: ();
|
|
|
76
85
|
display: none;
|
|
77
86
|
}
|
|
78
87
|
|
|
88
|
+
|
|
79
89
|
@include AlwaysVisibleElements;
|
|
80
|
-
|
|
81
|
-
@include
|
|
90
|
+
|
|
91
|
+
@include OrderElements;
|
|
82
92
|
|
|
83
93
|
}
|
|
84
94
|
|
|
@@ -1,24 +1,25 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react'
|
|
2
2
|
|
|
3
3
|
type FixedAspectRatioProps = {
|
|
4
4
|
width: number
|
|
5
5
|
height: number
|
|
6
6
|
style?: React.CSSProperties
|
|
7
7
|
element?: string
|
|
8
|
+
[key:string]: string | boolean | React.ReactNode | React.CSSProperties
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* High Order Component that forces a fixed aspect ratio to prevent Cumulative Layout Shift
|
|
12
13
|
* for elements that have a deterministic aspect ratio server-side
|
|
13
14
|
*/
|
|
14
|
-
export
|
|
15
|
+
export const FixedAspectRatio: React.FC<React.PropsWithChildren<FixedAspectRatioProps>> = ({
|
|
15
16
|
width,
|
|
16
17
|
height,
|
|
17
18
|
children,
|
|
18
19
|
style = {},
|
|
19
20
|
element = 'div',
|
|
20
|
-
...
|
|
21
|
-
}
|
|
21
|
+
...otherProps
|
|
22
|
+
}) => {
|
|
22
23
|
let fixedAspectRatioStyles
|
|
23
24
|
if (!width || !height) {
|
|
24
25
|
fixedAspectRatioStyles = {
|
|
@@ -34,7 +35,7 @@ export function FixedAspectRatio<P extends object = object>({
|
|
|
34
35
|
|
|
35
36
|
return React.createElement(
|
|
36
37
|
element,
|
|
37
|
-
{ ...
|
|
38
|
+
{ ...otherProps, style: { ...style, ...fixedAspectRatioStyles } },
|
|
38
39
|
children
|
|
39
40
|
)
|
|
40
41
|
}
|
|
@@ -37,7 +37,7 @@ const DisclaimerNotice = ({ id }: disclaimerProps) => (
|
|
|
37
37
|
</div>
|
|
38
38
|
</div>
|
|
39
39
|
)
|
|
40
|
-
|
|
40
|
+
const Flourish: React.FC<FlourishProps> = ({
|
|
41
41
|
id,
|
|
42
42
|
flourishType,
|
|
43
43
|
description,
|
|
@@ -45,7 +45,7 @@ export default function Flourish({
|
|
|
45
45
|
fallbackImage,
|
|
46
46
|
iFrame = false,
|
|
47
47
|
inArticleBody = true,
|
|
48
|
-
}
|
|
48
|
+
}) => {
|
|
49
49
|
if (!id) return null
|
|
50
50
|
const anchorHref = `#${id}`
|
|
51
51
|
const fullGrid = layoutWidth === 'full-grid' || layoutWidth === 'grid'
|
|
@@ -115,3 +115,5 @@ export default function Flourish({
|
|
|
115
115
|
</div>
|
|
116
116
|
)
|
|
117
117
|
}
|
|
118
|
+
|
|
119
|
+
export default Flourish
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import type { ReactNode } from 'react'
|
|
3
2
|
import type { ContentTree } from '@financial-times/content-tree'
|
|
4
3
|
|
|
5
|
-
|
|
4
|
+
const Heading: React.FC<React.PropsWithChildren<ContentTree.Heading>> = (
|
|
5
|
+
props
|
|
6
|
+
) => {
|
|
6
7
|
if (!props.children.length) return null
|
|
7
8
|
|
|
8
9
|
switch (props.level) {
|
|
@@ -14,3 +15,5 @@ export default (props: ContentTree.Heading & { children: ReactNode[] }) => {
|
|
|
14
15
|
return <h5 className="n-content-heading-5">{props.children}</h5>
|
|
15
16
|
}
|
|
16
17
|
}
|
|
18
|
+
|
|
19
|
+
export default Heading
|
|
@@ -8,13 +8,13 @@ type HeadshotProps = {
|
|
|
8
8
|
altText?: string
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
const Headshot: React.FC<HeadshotProps> = ({
|
|
12
12
|
headshot,
|
|
13
13
|
prefLabel,
|
|
14
14
|
streamPage,
|
|
15
15
|
className,
|
|
16
16
|
altText = `Headshot for ${prefLabel}`,
|
|
17
|
-
}
|
|
17
|
+
}) => {
|
|
18
18
|
return streamPage ? (
|
|
19
19
|
<a
|
|
20
20
|
target="_blank"
|
|
@@ -37,3 +37,5 @@ export default function Headshot({
|
|
|
37
37
|
/>
|
|
38
38
|
)
|
|
39
39
|
}
|
|
40
|
+
|
|
41
|
+
export default Headshot
|
|
@@ -80,11 +80,6 @@ function isAliasedBreakpoints(
|
|
|
80
80
|
)
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
type SourceProps = {
|
|
84
|
-
image: ImageFragment
|
|
85
|
-
getBreakpoints?: BreakpointGetter
|
|
86
|
-
}
|
|
87
|
-
|
|
88
83
|
function figureWidth(picture: PictureFragment) {
|
|
89
84
|
if (picture.layoutWidth === 'inset-left') {
|
|
90
85
|
const DEFAULT_WIDTH = 700
|
|
@@ -101,10 +96,15 @@ function figureWidth(picture: PictureFragment) {
|
|
|
101
96
|
}
|
|
102
97
|
}
|
|
103
98
|
|
|
104
|
-
|
|
99
|
+
type SourceProps = {
|
|
100
|
+
image: ImageFragment
|
|
101
|
+
getBreakpoints?: BreakpointGetter
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const Source: React.FC<SourceProps> = ({
|
|
105
105
|
image,
|
|
106
106
|
getBreakpoints = defaultGetBreakpoints,
|
|
107
|
-
}
|
|
107
|
+
}) => {
|
|
108
108
|
const breakpoints = getBreakpoints(image)
|
|
109
109
|
if (!breakpoints) {
|
|
110
110
|
return null
|
|
@@ -145,7 +145,7 @@ type SourcesProps = {
|
|
|
145
145
|
getBreakpoints?: BreakpointGetter
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
export
|
|
148
|
+
export const Sources: React.FC<SourcesProps> = ({ images, getBreakpoints }) => {
|
|
149
149
|
return (
|
|
150
150
|
<>
|
|
151
151
|
{images.map((image, index) => (
|
|
@@ -155,22 +155,24 @@ export function Sources({ images, getBreakpoints }: SourcesProps) {
|
|
|
155
155
|
)
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
+
type FallbackImageProps = {
|
|
159
|
+
image: ImageFragment
|
|
160
|
+
imageType?: string
|
|
161
|
+
picture?: PictureFragment
|
|
162
|
+
className?: string
|
|
163
|
+
inSourceSet?: boolean
|
|
164
|
+
isMainImage?: boolean
|
|
165
|
+
}
|
|
166
|
+
|
|
158
167
|
// TODO should `fallback` be added to content-tree imageset?
|
|
159
|
-
export
|
|
168
|
+
export const FallbackImage: React.FC<FallbackImageProps> = ({
|
|
160
169
|
image,
|
|
161
170
|
imageType = 'image',
|
|
162
171
|
picture,
|
|
163
172
|
className,
|
|
164
173
|
inSourceSet = false,
|
|
165
174
|
isMainImage = false,
|
|
166
|
-
}
|
|
167
|
-
image: ImageFragment
|
|
168
|
-
imageType?: string
|
|
169
|
-
picture?: PictureFragment
|
|
170
|
-
className?: string
|
|
171
|
-
inSourceSet?: boolean
|
|
172
|
-
isMainImage?: boolean
|
|
173
|
-
}) {
|
|
175
|
+
}) => {
|
|
174
176
|
const Wrapper = inSourceSet
|
|
175
177
|
? React.Fragment
|
|
176
178
|
: ({ children }: PropsWithChildren) => (
|
|
@@ -199,15 +201,15 @@ export function FallbackImage({
|
|
|
199
201
|
)
|
|
200
202
|
}
|
|
201
203
|
|
|
202
|
-
|
|
203
|
-
imageSet: ImageSetFragment & { isMainImage?: boolean }
|
|
204
|
-
) {
|
|
205
|
-
const { reduceFullBleedImages } = useContext(PresentationFlagsContext)
|
|
204
|
+
type ImageSetProps = ImageSetFragment & { isMainImage?: boolean }
|
|
206
205
|
|
|
206
|
+
const ImageSet: React.FC<ImageSetProps> = (imageSet) => {
|
|
207
207
|
if (!imageSet.picture?.images) {
|
|
208
208
|
return null
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
+
const { reduceFullBleedImages } = useContext(PresentationFlagsContext)
|
|
212
|
+
|
|
211
213
|
const Wrapper =
|
|
212
214
|
// HACK:20240618:IM don't stretch out the main image to the full grid in
|
|
213
215
|
// the app as it can clash with the right hand rail
|
|
@@ -253,3 +255,5 @@ export default function ImageSet(
|
|
|
253
255
|
</Wrapper>
|
|
254
256
|
)
|
|
255
257
|
}
|
|
258
|
+
|
|
259
|
+
export default ImageSet
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { ContentTree } from '@financial-times/content-tree'
|
|
2
|
-
import React
|
|
3
|
-
|
|
4
|
-
type LayoutContainerProps = {
|
|
5
|
-
children: ReactNode
|
|
6
|
-
}
|
|
2
|
+
import React from 'react'
|
|
7
3
|
|
|
8
4
|
interface ContentTreeLayoutSlot extends ContentTree.Node {
|
|
9
5
|
type: 'slot'
|
|
@@ -21,20 +17,15 @@ interface ContentTreeCardLayout extends BaseLayoutProps, ContentTree.Node {
|
|
|
21
17
|
children: ContentTreeLayoutSlot[]
|
|
22
18
|
}
|
|
23
19
|
|
|
24
|
-
interface StaticLayout extends BaseLayoutProps {
|
|
25
|
-
children: ReactNode
|
|
26
|
-
}
|
|
27
20
|
/*
|
|
28
21
|
* @description Layout component is used to define the layout for content. It can be used with ContentTree Layout Nodes or as a static layout.
|
|
29
22
|
* @param layoutWidth - The width of the layout within the containing grid.
|
|
30
23
|
* @param layoutName - The name of the layout.
|
|
31
24
|
* @param children - The content to be displayed in the layout.
|
|
32
25
|
*/
|
|
33
|
-
export
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
layoutName = 'auto',
|
|
37
|
-
}: React.PropsWithChildren<ContentTreeCardLayout | StaticLayout>) {
|
|
26
|
+
export const Layout: React.FC<
|
|
27
|
+
React.PropsWithChildren<ContentTreeCardLayout | BaseLayoutProps>
|
|
28
|
+
> = ({ children, layoutWidth, layoutName = 'auto' }) => {
|
|
38
29
|
return (
|
|
39
30
|
<div
|
|
40
31
|
className="n-content-layout"
|
|
@@ -46,10 +37,12 @@ export function Layout({
|
|
|
46
37
|
)
|
|
47
38
|
}
|
|
48
39
|
|
|
49
|
-
export
|
|
40
|
+
export const LayoutContainer: React.FC<React.PropsWithChildren> = ({
|
|
41
|
+
children,
|
|
42
|
+
}) => {
|
|
50
43
|
return <div className="n-content-layout__container">{children}</div>
|
|
51
44
|
}
|
|
52
45
|
|
|
53
|
-
export
|
|
46
|
+
export const LayoutSlot: React.FC<React.PropsWithChildren> = ({ children }) => {
|
|
54
47
|
return <div className="n-content-layout__slot">{children}</div>
|
|
55
48
|
}
|
|
@@ -10,13 +10,13 @@ type LiveBlogBodyProps = BodyProps & {
|
|
|
10
10
|
xInteractionSerialiser?: any
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
const LiveBlogBody: React.FC<LiveBlogBodyProps> = ({
|
|
14
14
|
content,
|
|
15
15
|
richTextComponents,
|
|
16
16
|
xInteractionSerialiser,
|
|
17
17
|
showShareButtons,
|
|
18
18
|
postTrackerConfig,
|
|
19
|
-
}
|
|
19
|
+
}) => {
|
|
20
20
|
if (content.__typename !== 'LiveBlogPackage') return null
|
|
21
21
|
|
|
22
22
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -35,3 +35,5 @@ export default function LiveBlogBody({
|
|
|
35
35
|
</ComponentsContext.Provider>
|
|
36
36
|
)
|
|
37
37
|
}
|
|
38
|
+
|
|
39
|
+
export default LiveBlogBody
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { FacebookSVG, LinkedInSVG, TwitterSVG } from './svgIcons'
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
articleUrl,
|
|
6
|
-
title,
|
|
7
|
-
}: {
|
|
3
|
+
|
|
4
|
+
type ShareButtonsProps = {
|
|
8
5
|
postId: string
|
|
9
6
|
articleUrl: string
|
|
10
7
|
title: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const ShareButtons: React.FC<ShareButtonsProps> = ({
|
|
11
|
+
postId,
|
|
12
|
+
articleUrl,
|
|
13
|
+
title,
|
|
11
14
|
}) => {
|
|
12
15
|
const shareUrl = articleUrl ? new URL(articleUrl) : null
|
|
13
16
|
if (shareUrl) {
|
|
@@ -84,3 +87,5 @@ export default ({
|
|
|
84
87
|
</div>
|
|
85
88
|
)
|
|
86
89
|
}
|
|
90
|
+
|
|
91
|
+
export default ShareButtons
|
|
@@ -5,7 +5,10 @@ type TimestampProps = {
|
|
|
5
5
|
textCase?: 'sentence'
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
const TimeStamp: React.FC<TimestampProps> = ({
|
|
9
|
+
publishedTimestamp,
|
|
10
|
+
textCase,
|
|
11
|
+
}) => {
|
|
9
12
|
const now = new Date()
|
|
10
13
|
const oneDay = 24 * 60 * 60 * 1000
|
|
11
14
|
const date = new Date(publishedTimestamp)
|
|
@@ -38,3 +41,5 @@ export default ({ publishedTimestamp, textCase }: TimestampProps) => {
|
|
|
38
41
|
</span>
|
|
39
42
|
)
|
|
40
43
|
}
|
|
44
|
+
|
|
45
|
+
export default TimeStamp
|
|
@@ -16,7 +16,10 @@ type indicators = {
|
|
|
16
16
|
isOpinion?: boolean
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
const TruncatedPost
|
|
19
|
+
const TruncatedPost: React.FC<React.PropsWithChildren<{ id: string }>> = ({
|
|
20
|
+
id,
|
|
21
|
+
children,
|
|
22
|
+
}) => {
|
|
20
23
|
return (
|
|
21
24
|
<div
|
|
22
25
|
data-trackable="truncated-post"
|
|
@@ -77,8 +80,7 @@ export type LiveBlogPostProps = {
|
|
|
77
80
|
indicators?: indicators
|
|
78
81
|
authors: Array<any>
|
|
79
82
|
}
|
|
80
|
-
|
|
81
|
-
const LiveBlogPost = ({
|
|
83
|
+
const LiveBlogPost: React.FC<LiveBlogPostProps> = ({
|
|
82
84
|
id,
|
|
83
85
|
postId, // Remove once wordpress is no longer in use
|
|
84
86
|
title,
|
|
@@ -96,7 +98,7 @@ const LiveBlogPost = ({
|
|
|
96
98
|
isPinned,
|
|
97
99
|
indicators = {},
|
|
98
100
|
authors,
|
|
99
|
-
}
|
|
101
|
+
}) => {
|
|
100
102
|
const showBreakingNewsLabel = standout.breakingNews || isBreakingNews
|
|
101
103
|
|
|
102
104
|
let postBody
|
|
@@ -5,7 +5,7 @@ TODO: CI-1975 given the below comment, once we are happy this migration works, w
|
|
|
5
5
|
These icons have been copied from Origami as their TSX components are currently incompatible with next-article.
|
|
6
6
|
Once this is resolved, these components should be replaced with o-share https://github.com/Financial-Times/origami/tree/main/components/o-share.
|
|
7
7
|
*/
|
|
8
|
-
export
|
|
8
|
+
export const TwitterSVG: React.FC = () => {
|
|
9
9
|
return (
|
|
10
10
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40">
|
|
11
11
|
<path d="M21.647 18.469 28.932 10h-1.726l-6.326 7.353L15.827 10H10l7.64 11.12L10 30h1.726l6.68-7.765L23.744 30h5.827l-7.924-11.531Zm-2.365 2.748-.774-1.107-6.16-8.81H15l4.971 7.11.774 1.107 6.462 9.242h-2.652l-5.273-7.541Z" />
|
|
@@ -13,7 +13,7 @@ export function TwitterSVG() {
|
|
|
13
13
|
)
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
export
|
|
16
|
+
export const FacebookSVG: React.FC = () => {
|
|
17
17
|
return (
|
|
18
18
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
|
|
19
19
|
<path d="M643.9 342h-48.2c-37.8 0-45.1 18-45.1 44.3v58.1h90.1l-11.7 91h-78.4V769h-94V535.5H378v-91h78.6v-67.1c0-77.9 47.6-120.3 117.1-120.3 33.3 0 61.9 2.5 70.2 3.6V342z" />
|
|
@@ -21,7 +21,7 @@ export function FacebookSVG() {
|
|
|
21
21
|
)
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
export
|
|
24
|
+
export const LinkedInSVG: React.FC = () => {
|
|
25
25
|
return (
|
|
26
26
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
|
|
27
27
|
<path d="M264.4 426.2h106.2v341.4H264.4V426.2zm53.2-169.7c-34.1 0-61.6 27.6-61.6 61.5 0 34 27.5 61.5 61.6 61.5 33.9 0 61.5-27.6 61.5-61.5-.1-34-27.6-61.5-61.5-61.5zm323.1 161.2c-51.6 0-86.2 28.3-100.4 55.1h-1.5v-46.7H437.2v341.4h106V598.7c0-44.5 8.4-87.7 63.6-87.7 54.5 0 55.1 50.9 55.1 90.5v166H768V580.3c0-91.9-19.9-162.6-127.3-162.6z" />
|
|
@@ -10,7 +10,7 @@ import { ContentTree } from '@financial-times/content-tree'
|
|
|
10
10
|
type MainImageProps = {
|
|
11
11
|
content: ArticleQuery['content']
|
|
12
12
|
}
|
|
13
|
-
|
|
13
|
+
const MainImage: React.FC<MainImageProps> = ({ content }) => {
|
|
14
14
|
const references = content.body?.structured.references
|
|
15
15
|
|
|
16
16
|
/* Spark publishes the MainImage at the top of the <body>. if the image is expected to be rendered at all
|
|
@@ -37,3 +37,5 @@ export default function MainImage({ content }: MainImageProps) {
|
|
|
37
37
|
|
|
38
38
|
return null
|
|
39
39
|
}
|
|
40
|
+
|
|
41
|
+
export default MainImage
|