@financial-times/cp-content-pipeline-ui 6.4.5 → 6.5.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 +35 -0
- package/lib/client.d.ts +1 -0
- package/lib/client.js +3 -1
- package/lib/client.js.map +1 -1
- package/lib/components/Clip/client/index.d.ts +1 -0
- package/lib/components/Clip/client/index.js +1 -0
- package/lib/components/Clip/client/index.js.map +1 -1
- package/lib/components/Clip/client/progressBar.d.ts +0 -1
- package/lib/components/Clip/client/progressBar.js +10 -8
- package/lib/components/Clip/client/progressBar.js.map +1 -1
- package/lib/components/Clip/test/snapshot.spec.js +2 -0
- package/lib/components/Clip/test/snapshot.spec.js.map +1 -1
- package/lib/components/Flourish/client/index.d.ts +2 -0
- package/lib/components/Flourish/client/index.js +16 -0
- package/lib/components/Flourish/client/index.js.map +1 -0
- package/lib/components/Flourish/index.d.ts +16 -3
- package/lib/components/Flourish/index.js +21 -4
- package/lib/components/Flourish/index.js.map +1 -1
- package/lib/components/Flourish/test/snapshot.spec.d.ts +1 -0
- package/lib/components/Flourish/test/snapshot.spec.js +57 -0
- package/lib/components/Flourish/test/snapshot.spec.js.map +1 -0
- package/lib/components/Layout/index.d.ts +9 -3
- package/lib/components/Layout/index.js +7 -1
- package/lib/components/Layout/index.js.map +1 -1
- package/lib/components/PodcastBody/index.d.ts +2 -2
- package/lib/components/PodcastBody/index.js +2 -2
- package/lib/components/PodcastBody/index.js.map +1 -1
- package/lib/components/Topper/Headline.js +2 -2
- package/lib/components/Topper/Headline.js.map +1 -1
- package/lib/components/Topper/Intro.d.ts +1 -3
- package/lib/components/Topper/Intro.js +2 -2
- package/lib/components/Topper/Intro.js.map +1 -1
- package/lib/components/Topper/index.d.ts +2 -4
- package/lib/components/Topper/index.js +8 -2
- package/lib/components/Topper/index.js.map +1 -1
- package/lib/stories/Topper.stories.d.ts +9 -0
- package/lib/stories/Topper.stories.js +23 -0
- package/lib/stories/Topper.stories.js.map +1 -0
- package/lib/stories/content.d.ts +65 -0
- package/lib/stories/content.js +82 -0
- package/lib/stories/content.js.map +1 -0
- package/package.json +6 -5
- package/src/client.ts +1 -0
- package/src/components/Clip/client/index.ts +2 -0
- package/src/components/Clip/client/progressBar.ts +12 -8
- package/src/components/Clip/test/snapshot.spec.tsx +2 -0
- package/src/components/Flourish/client/index.ts +17 -0
- package/src/components/Flourish/client/main.scss +38 -0
- package/src/components/Flourish/index.tsx +55 -6
- package/src/components/Flourish/test/__snapshots__/snapshot.spec.tsx.snap +310 -0
- package/src/components/Flourish/test/snapshot.spec.tsx +115 -0
- package/src/components/Layout/index.tsx +17 -4
- package/src/components/PodcastBody/index.tsx +3 -3
- package/src/components/Topper/Headline.tsx +4 -2
- package/src/components/Topper/Intro.tsx +1 -8
- package/src/components/Topper/client/main.scss +5 -0
- package/src/components/Topper/index.tsx +21 -5
- package/src/stories/Topper.stories.tsx +22 -0
- package/src/stories/content.tsx +78 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`Flourish component renders ignoring layout different from full-grid 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="n-content-layout"
|
|
7
|
+
data-component="flourish"
|
|
8
|
+
>
|
|
9
|
+
<figure
|
|
10
|
+
class="n-content-picture n-content-layout__container"
|
|
11
|
+
>
|
|
12
|
+
<a
|
|
13
|
+
href="#123"
|
|
14
|
+
>
|
|
15
|
+
<picture
|
|
16
|
+
data-asset-type="flourish"
|
|
17
|
+
data-flourish-id="123"
|
|
18
|
+
data-flourish-type="bar"
|
|
19
|
+
>
|
|
20
|
+
<div
|
|
21
|
+
class="flourish-disclaimer o-message o-message--alert o-message--neutral"
|
|
22
|
+
data-o-component="o-message"
|
|
23
|
+
id="123"
|
|
24
|
+
>
|
|
25
|
+
<div
|
|
26
|
+
class="o-message__container"
|
|
27
|
+
>
|
|
28
|
+
<div
|
|
29
|
+
class="o-message__content"
|
|
30
|
+
>
|
|
31
|
+
<p
|
|
32
|
+
class="o-message__content-main"
|
|
33
|
+
>
|
|
34
|
+
You are seeing a snapshot of an interactive graphic. This is most likely due to being offline or JavaScript being disabled in your browser.
|
|
35
|
+
</p>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
<img
|
|
40
|
+
alt="foo"
|
|
41
|
+
src="https://example.com/image.jpg"
|
|
42
|
+
/>
|
|
43
|
+
</picture>
|
|
44
|
+
</a>
|
|
45
|
+
</figure>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
`;
|
|
49
|
+
|
|
50
|
+
exports[`Flourish component renders with a full-grid layout and fallback image 1`] = `
|
|
51
|
+
<div>
|
|
52
|
+
<div
|
|
53
|
+
class="n-content-layout"
|
|
54
|
+
data-component="flourish"
|
|
55
|
+
data-layout-width="full-grid"
|
|
56
|
+
>
|
|
57
|
+
<figure
|
|
58
|
+
class="n-content-picture n-content-layout__container n-content-picture--wide"
|
|
59
|
+
data-original-image-height="150"
|
|
60
|
+
data-original-image-width="100"
|
|
61
|
+
>
|
|
62
|
+
<a
|
|
63
|
+
href="#123"
|
|
64
|
+
>
|
|
65
|
+
<picture
|
|
66
|
+
data-asset-type="flourish"
|
|
67
|
+
data-flourish-id="123"
|
|
68
|
+
data-flourish-type="bar"
|
|
69
|
+
>
|
|
70
|
+
<div
|
|
71
|
+
class="flourish-disclaimer o-message o-message--alert o-message--neutral"
|
|
72
|
+
data-o-component="o-message"
|
|
73
|
+
id="123"
|
|
74
|
+
>
|
|
75
|
+
<div
|
|
76
|
+
class="o-message__container"
|
|
77
|
+
>
|
|
78
|
+
<div
|
|
79
|
+
class="o-message__content"
|
|
80
|
+
>
|
|
81
|
+
<p
|
|
82
|
+
class="o-message__content-main"
|
|
83
|
+
>
|
|
84
|
+
You are seeing a snapshot of an interactive graphic. This is most likely due to being offline or JavaScript being disabled in your browser.
|
|
85
|
+
</p>
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
<img
|
|
90
|
+
alt="foo"
|
|
91
|
+
src="https://example.com/image.jpg"
|
|
92
|
+
/>
|
|
93
|
+
</picture>
|
|
94
|
+
</a>
|
|
95
|
+
</figure>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
`;
|
|
99
|
+
|
|
100
|
+
exports[`Flourish component renders with an iframe rather than using the embed script to insert it 1`] = `
|
|
101
|
+
<div>
|
|
102
|
+
<div
|
|
103
|
+
class="n-content-layout flourish flourish--iFrame"
|
|
104
|
+
data-component="flourish"
|
|
105
|
+
data-layout-width="full-grid"
|
|
106
|
+
>
|
|
107
|
+
<iframe
|
|
108
|
+
class="flourish__i-frame"
|
|
109
|
+
src="https://flo.uri.sh/visualisation/123/embed?hideTitle=false"
|
|
110
|
+
style="width: 100%;"
|
|
111
|
+
/>
|
|
112
|
+
<figure
|
|
113
|
+
class="n-content-picture n-content-layout__container n-content-picture--wide flourish__figure"
|
|
114
|
+
data-original-image-height="150"
|
|
115
|
+
data-original-image-width="100"
|
|
116
|
+
>
|
|
117
|
+
<a
|
|
118
|
+
href="#123"
|
|
119
|
+
>
|
|
120
|
+
<picture
|
|
121
|
+
data-asset-type="flourish-embed"
|
|
122
|
+
data-flourish-id="123"
|
|
123
|
+
data-flourish-type="bar"
|
|
124
|
+
>
|
|
125
|
+
<div
|
|
126
|
+
class="flourish-disclaimer o-message o-message--alert o-message--neutral"
|
|
127
|
+
data-o-component="o-message"
|
|
128
|
+
id="123"
|
|
129
|
+
>
|
|
130
|
+
<div
|
|
131
|
+
class="o-message__container"
|
|
132
|
+
>
|
|
133
|
+
<div
|
|
134
|
+
class="o-message__content"
|
|
135
|
+
>
|
|
136
|
+
<p
|
|
137
|
+
class="o-message__content-main"
|
|
138
|
+
>
|
|
139
|
+
You are seeing a snapshot of an interactive graphic. This is most likely due to being offline or JavaScript being disabled in your browser.
|
|
140
|
+
</p>
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
</div>
|
|
144
|
+
<img
|
|
145
|
+
alt="foo"
|
|
146
|
+
src="https://example.com/image.jpg"
|
|
147
|
+
/>
|
|
148
|
+
</picture>
|
|
149
|
+
</a>
|
|
150
|
+
</figure>
|
|
151
|
+
</div>
|
|
152
|
+
</div>
|
|
153
|
+
`;
|
|
154
|
+
|
|
155
|
+
exports[`Flourish component renders without n-content-layout class for charts not in article body 1`] = `
|
|
156
|
+
<div>
|
|
157
|
+
<div
|
|
158
|
+
class=""
|
|
159
|
+
data-component="flourish"
|
|
160
|
+
data-layout-width="full-grid"
|
|
161
|
+
>
|
|
162
|
+
<figure
|
|
163
|
+
class="n-content-picture n-content-layout__container n-content-picture--wide"
|
|
164
|
+
data-original-image-height="150"
|
|
165
|
+
data-original-image-width="100"
|
|
166
|
+
>
|
|
167
|
+
<a
|
|
168
|
+
href="#123"
|
|
169
|
+
>
|
|
170
|
+
<picture
|
|
171
|
+
data-asset-type="flourish"
|
|
172
|
+
data-flourish-id="123"
|
|
173
|
+
data-flourish-type="bar"
|
|
174
|
+
>
|
|
175
|
+
<div
|
|
176
|
+
class="flourish-disclaimer o-message o-message--alert o-message--neutral"
|
|
177
|
+
data-o-component="o-message"
|
|
178
|
+
id="123"
|
|
179
|
+
>
|
|
180
|
+
<div
|
|
181
|
+
class="o-message__container"
|
|
182
|
+
>
|
|
183
|
+
<div
|
|
184
|
+
class="o-message__content"
|
|
185
|
+
>
|
|
186
|
+
<p
|
|
187
|
+
class="o-message__content-main"
|
|
188
|
+
>
|
|
189
|
+
You are seeing a snapshot of an interactive graphic. This is most likely due to being offline or JavaScript being disabled in your browser.
|
|
190
|
+
</p>
|
|
191
|
+
</div>
|
|
192
|
+
</div>
|
|
193
|
+
</div>
|
|
194
|
+
<img
|
|
195
|
+
alt="foo"
|
|
196
|
+
src="https://example.com/image.jpg"
|
|
197
|
+
style="width: 100%;"
|
|
198
|
+
/>
|
|
199
|
+
</picture>
|
|
200
|
+
</a>
|
|
201
|
+
</figure>
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
`;
|
|
205
|
+
|
|
206
|
+
exports[`does not set aspect ratios when in article body 1`] = `
|
|
207
|
+
<div>
|
|
208
|
+
<div
|
|
209
|
+
class="n-content-layout"
|
|
210
|
+
data-component="flourish"
|
|
211
|
+
data-layout-width="full-grid"
|
|
212
|
+
>
|
|
213
|
+
<figure
|
|
214
|
+
class="n-content-picture n-content-layout__container n-content-picture--wide"
|
|
215
|
+
data-original-image-height="150"
|
|
216
|
+
data-original-image-width="100"
|
|
217
|
+
>
|
|
218
|
+
<a
|
|
219
|
+
href="#123"
|
|
220
|
+
>
|
|
221
|
+
<picture
|
|
222
|
+
data-asset-type="flourish"
|
|
223
|
+
data-flourish-id="123"
|
|
224
|
+
data-flourish-type="bar"
|
|
225
|
+
>
|
|
226
|
+
<div
|
|
227
|
+
class="flourish-disclaimer o-message o-message--alert o-message--neutral"
|
|
228
|
+
data-o-component="o-message"
|
|
229
|
+
id="123"
|
|
230
|
+
>
|
|
231
|
+
<div
|
|
232
|
+
class="o-message__container"
|
|
233
|
+
>
|
|
234
|
+
<div
|
|
235
|
+
class="o-message__content"
|
|
236
|
+
>
|
|
237
|
+
<p
|
|
238
|
+
class="o-message__content-main"
|
|
239
|
+
>
|
|
240
|
+
You are seeing a snapshot of an interactive graphic. This is most likely due to being offline or JavaScript being disabled in your browser.
|
|
241
|
+
</p>
|
|
242
|
+
</div>
|
|
243
|
+
</div>
|
|
244
|
+
</div>
|
|
245
|
+
<img
|
|
246
|
+
alt="foo"
|
|
247
|
+
src="https://example.com/image.jpg"
|
|
248
|
+
/>
|
|
249
|
+
</picture>
|
|
250
|
+
</a>
|
|
251
|
+
</figure>
|
|
252
|
+
</div>
|
|
253
|
+
</div>
|
|
254
|
+
`;
|
|
255
|
+
|
|
256
|
+
exports[`sets the hideTitle param in the iframe url to true when not in article body 1`] = `
|
|
257
|
+
<div>
|
|
258
|
+
<div
|
|
259
|
+
class="flourish flourish--iFrame"
|
|
260
|
+
data-component="flourish"
|
|
261
|
+
data-layout-width="full-grid"
|
|
262
|
+
>
|
|
263
|
+
<iframe
|
|
264
|
+
class="flourish__i-frame"
|
|
265
|
+
src="https://flo.uri.sh/visualisation/123/embed?hideTitle=true"
|
|
266
|
+
style="width: 100%;"
|
|
267
|
+
/>
|
|
268
|
+
<figure
|
|
269
|
+
class="n-content-picture n-content-layout__container n-content-picture--wide flourish__figure"
|
|
270
|
+
data-original-image-height="150"
|
|
271
|
+
data-original-image-width="100"
|
|
272
|
+
>
|
|
273
|
+
<a
|
|
274
|
+
href="#123"
|
|
275
|
+
>
|
|
276
|
+
<picture
|
|
277
|
+
data-asset-type="flourish-embed"
|
|
278
|
+
data-flourish-id="123"
|
|
279
|
+
data-flourish-type="bar"
|
|
280
|
+
>
|
|
281
|
+
<div
|
|
282
|
+
class="flourish-disclaimer o-message o-message--alert o-message--neutral"
|
|
283
|
+
data-o-component="o-message"
|
|
284
|
+
id="123"
|
|
285
|
+
>
|
|
286
|
+
<div
|
|
287
|
+
class="o-message__container"
|
|
288
|
+
>
|
|
289
|
+
<div
|
|
290
|
+
class="o-message__content"
|
|
291
|
+
>
|
|
292
|
+
<p
|
|
293
|
+
class="o-message__content-main"
|
|
294
|
+
>
|
|
295
|
+
You are seeing a snapshot of an interactive graphic. This is most likely due to being offline or JavaScript being disabled in your browser.
|
|
296
|
+
</p>
|
|
297
|
+
</div>
|
|
298
|
+
</div>
|
|
299
|
+
</div>
|
|
300
|
+
<img
|
|
301
|
+
alt="foo"
|
|
302
|
+
src="https://example.com/image.jpg"
|
|
303
|
+
style="width: 100%;"
|
|
304
|
+
/>
|
|
305
|
+
</picture>
|
|
306
|
+
</a>
|
|
307
|
+
</figure>
|
|
308
|
+
</div>
|
|
309
|
+
</div>
|
|
310
|
+
`;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render } from '@testing-library/react'
|
|
3
|
+
import Flourish from '../'
|
|
4
|
+
|
|
5
|
+
enum acceptedFormat {
|
|
6
|
+
standard = 'standard',
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const anImage = {
|
|
10
|
+
id: '123',
|
|
11
|
+
url: 'https://example.com/image.jpg',
|
|
12
|
+
width: 100,
|
|
13
|
+
height: 150,
|
|
14
|
+
format: 'standard' as acceptedFormat,
|
|
15
|
+
sourceSet: [
|
|
16
|
+
{
|
|
17
|
+
url: 'https://example.com/anotherImage.jpg',
|
|
18
|
+
width: 200,
|
|
19
|
+
dpr: 2,
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
}
|
|
23
|
+
describe('Flourish component', () => {
|
|
24
|
+
it('renders with a full-grid layout and fallback image', async () => {
|
|
25
|
+
const { container } = render(
|
|
26
|
+
<Flourish
|
|
27
|
+
type="flourish"
|
|
28
|
+
id="123"
|
|
29
|
+
flourishType="bar"
|
|
30
|
+
description="foo"
|
|
31
|
+
layoutWidth="full-grid"
|
|
32
|
+
fallbackImage={anImage}
|
|
33
|
+
/>
|
|
34
|
+
)
|
|
35
|
+
expect(container).toMatchSnapshot()
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it('renders ignoring layout different from full-grid', async () => {
|
|
39
|
+
const { container } = render(
|
|
40
|
+
<Flourish
|
|
41
|
+
type="flourish"
|
|
42
|
+
id="123"
|
|
43
|
+
flourishType="bar"
|
|
44
|
+
description="foo"
|
|
45
|
+
layoutWidth="whatever"
|
|
46
|
+
fallbackImage={anImage}
|
|
47
|
+
/>
|
|
48
|
+
)
|
|
49
|
+
expect(container).toMatchSnapshot()
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it('renders with an iframe rather than using the embed script to insert it', async () => {
|
|
53
|
+
const iFrame = true
|
|
54
|
+
const { container } = render(
|
|
55
|
+
<Flourish
|
|
56
|
+
type="flourish"
|
|
57
|
+
id="123"
|
|
58
|
+
flourishType="bar"
|
|
59
|
+
description="foo"
|
|
60
|
+
layoutWidth="full-grid"
|
|
61
|
+
fallbackImage={anImage}
|
|
62
|
+
iFrame={iFrame}
|
|
63
|
+
/>
|
|
64
|
+
)
|
|
65
|
+
expect(container).toMatchSnapshot()
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it('renders without n-content-layout class for charts not in article body', async () => {
|
|
69
|
+
const inArticleBody = false
|
|
70
|
+
const { container } = render(
|
|
71
|
+
<Flourish
|
|
72
|
+
type="flourish"
|
|
73
|
+
id="123"
|
|
74
|
+
flourishType="bar"
|
|
75
|
+
description="foo"
|
|
76
|
+
layoutWidth="full-grid"
|
|
77
|
+
fallbackImage={anImage}
|
|
78
|
+
inArticleBody={inArticleBody}
|
|
79
|
+
/>
|
|
80
|
+
)
|
|
81
|
+
expect(container).toMatchSnapshot()
|
|
82
|
+
})
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
it('sets the hideTitle param in the iframe url to true when not in article body', async () => {
|
|
86
|
+
const inArticleBody = false
|
|
87
|
+
const iFrame = true
|
|
88
|
+
const { container } = render(
|
|
89
|
+
<Flourish
|
|
90
|
+
type="flourish"
|
|
91
|
+
id="123"
|
|
92
|
+
flourishType="bar"
|
|
93
|
+
description="foo"
|
|
94
|
+
layoutWidth="full-grid"
|
|
95
|
+
fallbackImage={anImage}
|
|
96
|
+
iFrame={iFrame}
|
|
97
|
+
inArticleBody={inArticleBody}
|
|
98
|
+
/>
|
|
99
|
+
)
|
|
100
|
+
expect(container).toMatchSnapshot()
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
it('does not set aspect ratios when in article body', async () => {
|
|
104
|
+
const { container } = render(
|
|
105
|
+
<Flourish
|
|
106
|
+
type="flourish"
|
|
107
|
+
id="123"
|
|
108
|
+
flourishType="bar"
|
|
109
|
+
description="foo"
|
|
110
|
+
layoutWidth="full-grid"
|
|
111
|
+
fallbackImage={anImage}
|
|
112
|
+
/>
|
|
113
|
+
)
|
|
114
|
+
expect(container).toMatchSnapshot()
|
|
115
|
+
})
|
|
@@ -10,18 +10,31 @@ interface ContentTreeLayoutSlot extends ContentTree.Node {
|
|
|
10
10
|
children: [ContentTree.ImageSet?, ...ContentTree.Paragraph[]]
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
interface
|
|
13
|
+
interface BaseLayoutProps {
|
|
14
|
+
layoutWidth: 'inset-left' | 'full-width' | 'full-grid'
|
|
15
|
+
layoutName?: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface ContentTreeCardLayout extends BaseLayoutProps, ContentTree.Node {
|
|
14
19
|
type: 'layout'
|
|
15
20
|
layoutName: 'auto' | 'card' | 'timeline'
|
|
16
|
-
layoutWidth: 'inset-left' | 'full-width' | 'full-grid'
|
|
17
21
|
children: ContentTreeLayoutSlot[]
|
|
18
22
|
}
|
|
19
23
|
|
|
24
|
+
interface StaticLayout extends BaseLayoutProps {
|
|
25
|
+
children: ReactNode
|
|
26
|
+
}
|
|
27
|
+
/*
|
|
28
|
+
* @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
|
+
* @param layoutWidth - The width of the layout within the containing grid.
|
|
30
|
+
* @param layoutName - The name of the layout.
|
|
31
|
+
* @param children - The content to be displayed in the layout.
|
|
32
|
+
*/
|
|
20
33
|
export function Layout({
|
|
21
34
|
children,
|
|
22
35
|
layoutWidth,
|
|
23
|
-
layoutName,
|
|
24
|
-
}: React.PropsWithChildren<ContentTreeCardLayout>) {
|
|
36
|
+
layoutName = 'auto',
|
|
37
|
+
}: React.PropsWithChildren<ContentTreeCardLayout | StaticLayout>) {
|
|
25
38
|
return (
|
|
26
39
|
<div
|
|
27
40
|
className="n-content-layout"
|
|
@@ -6,8 +6,8 @@ export default function PodcastBody({
|
|
|
6
6
|
content,
|
|
7
7
|
richTextComponents,
|
|
8
8
|
showPlayer = true,
|
|
9
|
-
|
|
10
|
-
}: BodyProps & { showPlayer?: boolean;
|
|
9
|
+
showAccessibilityGuide = true,
|
|
10
|
+
}: BodyProps & { showPlayer?: boolean; showAccessibilityGuide?: boolean }) {
|
|
11
11
|
if (content.__typename !== 'Audio') {
|
|
12
12
|
return null
|
|
13
13
|
}
|
|
@@ -47,7 +47,7 @@ export default function PodcastBody({
|
|
|
47
47
|
structuredContent={content.body.structured}
|
|
48
48
|
components={richTextComponents}
|
|
49
49
|
/>
|
|
50
|
-
{
|
|
50
|
+
{showAccessibilityGuide && (
|
|
51
51
|
<p>
|
|
52
52
|
<a href="/accessibility#podcast-transcriptions">
|
|
53
53
|
View our accessibility guide
|
|
@@ -23,9 +23,11 @@ export default function Headline({
|
|
|
23
23
|
|
|
24
24
|
return (
|
|
25
25
|
<h1 className={headlineClassnames}>
|
|
26
|
-
<span className="
|
|
26
|
+
<span className="headline__text">{headline}</span>
|
|
27
27
|
{showPremiumLabel && (
|
|
28
|
-
<span className="o-labels o-labels--content-premium">
|
|
28
|
+
<span className="headline__premium-badge o-labels o-labels--content-premium">
|
|
29
|
+
Premium
|
|
30
|
+
</span>
|
|
29
31
|
)}
|
|
30
32
|
</h1>
|
|
31
33
|
)
|
|
@@ -3,16 +3,9 @@ import RichText from '../RichText'
|
|
|
3
3
|
import type { IntroFragment } from '@financial-times/cp-content-pipeline-client'
|
|
4
4
|
import classNames from 'classnames'
|
|
5
5
|
|
|
6
|
-
export default function Intro({
|
|
7
|
-
structured,
|
|
8
|
-
source,
|
|
9
|
-
handleSummaryLinkClick,
|
|
10
|
-
}: IntroFragment & {
|
|
11
|
-
handleSummaryLinkClick?: (event: React.MouseEvent<HTMLElement>) => void
|
|
12
|
-
}) {
|
|
6
|
+
export default function Intro({ structured, source }: IntroFragment) {
|
|
13
7
|
return (
|
|
14
8
|
<div
|
|
15
|
-
onClick={handleSummaryLinkClick}
|
|
16
9
|
className={classNames(`o-topper__${source}`, {
|
|
17
10
|
'o-topper__summary--body': source === 'summary',
|
|
18
11
|
})}
|
|
@@ -8,16 +8,17 @@ import Headshot from '../Headshot'
|
|
|
8
8
|
import Columnist from './Columnist'
|
|
9
9
|
import LiveBlogIndicator from './LiveBlogIndicator'
|
|
10
10
|
import { FollowButtonSlot } from './FollowButtonSlot'
|
|
11
|
+
import Flourish from '../Flourish'
|
|
12
|
+
import { Layout, LayoutContainer } from '../Layout'
|
|
11
13
|
import classnames from 'classnames'
|
|
12
14
|
import type { ArticleQuery } from '@financial-times/cp-content-pipeline-client'
|
|
13
15
|
|
|
14
|
-
type TopperProps = {
|
|
16
|
+
export type TopperProps = {
|
|
15
17
|
content: ArticleQuery['content']
|
|
16
18
|
slot?: string
|
|
17
19
|
followButtonSlot?: FollowButtonSlot
|
|
18
20
|
showPremiumLabel?: boolean
|
|
19
21
|
readNextSlot?: () => ReactElement
|
|
20
|
-
handleSummaryLinkClick?: (event: React.MouseEvent<HTMLElement>) => void
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
export default function Topper({
|
|
@@ -26,7 +27,6 @@ export default function Topper({
|
|
|
26
27
|
followButtonSlot,
|
|
27
28
|
showPremiumLabel = false,
|
|
28
29
|
readNextSlot,
|
|
29
|
-
handleSummaryLinkClick,
|
|
30
30
|
}: TopperProps) {
|
|
31
31
|
const { topper } = content
|
|
32
32
|
|
|
@@ -39,6 +39,8 @@ export default function Topper({
|
|
|
39
39
|
const isBasic = topper.__typename === 'BasicTopper'
|
|
40
40
|
const isOpinion = topper.__typename === 'OpinionTopper'
|
|
41
41
|
const isPodcast = topper.__typename === 'PodcastTopper'
|
|
42
|
+
const isFlourish =
|
|
43
|
+
topper.__typename === 'TopperWithFlourish' && !!topper.leadFlourish
|
|
42
44
|
const isAudio = content.__typename === 'Audio'
|
|
43
45
|
const hasLayout = 'layout' in topper && topper.layout
|
|
44
46
|
const hasDesign = 'design' in topper && topper.design
|
|
@@ -136,14 +138,28 @@ export default function Topper({
|
|
|
136
138
|
undefined
|
|
137
139
|
}
|
|
138
140
|
/>
|
|
141
|
+
{isLiveBlog && isFlourish ? (
|
|
142
|
+
<Layout layoutWidth="full-grid">
|
|
143
|
+
<LayoutContainer>
|
|
144
|
+
<Flourish
|
|
145
|
+
id={topper.leadFlourish.id || ''}
|
|
146
|
+
flourishType={topper.leadFlourish.type || ''}
|
|
147
|
+
description={topper.leadFlourish.description || ''}
|
|
148
|
+
fallbackImage={topper.leadFlourish.fallbackImage || ''}
|
|
149
|
+
iFrame={true}
|
|
150
|
+
inArticleBody={false}
|
|
151
|
+
/>
|
|
152
|
+
</LayoutContainer>
|
|
153
|
+
</Layout>
|
|
154
|
+
) : (
|
|
155
|
+
''
|
|
156
|
+
)}
|
|
139
157
|
{topper.intro && (
|
|
140
158
|
<Intro
|
|
141
159
|
structured={topper.intro.structured}
|
|
142
160
|
source={topper.intro.source}
|
|
143
|
-
handleSummaryLinkClick={handleSummaryLinkClick}
|
|
144
161
|
/>
|
|
145
162
|
)}
|
|
146
|
-
|
|
147
163
|
{hasHeadshot && !isAudio && isOpinion && topper.columnist && (
|
|
148
164
|
<div className="o-topper__headshot">
|
|
149
165
|
<Headshot
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import Topper, { TopperProps } from "../components/Topper";
|
|
3
|
+
import { content } from './content';
|
|
4
|
+
import type { ArticleQuery } from '@financial-times/cp-content-pipeline-client'
|
|
5
|
+
|
|
6
|
+
const args: TopperProps = {
|
|
7
|
+
content: content as unknown as ArticleQuery['content']
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default {
|
|
11
|
+
title: 'Topper',
|
|
12
|
+
component: Topper,
|
|
13
|
+
content: {}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const Default = () => {
|
|
17
|
+
return (
|
|
18
|
+
<div className="story-container">
|
|
19
|
+
<Topper {...args} />
|
|
20
|
+
</div>
|
|
21
|
+
)
|
|
22
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
export const content = {
|
|
2
|
+
__typename: 'LiveBlogPackage',
|
|
3
|
+
id: 'f9d0da8a-ac43-4f0d-8af5-d597d1f13bb8',
|
|
4
|
+
title: 'News updates from February 2: US adds 353,000 jobs in January, US hits Iraq and Syria after drone deaths',
|
|
5
|
+
publishedDate: '2024-02-05T12:00:44.399Z',
|
|
6
|
+
firstPublishedDate: '2024-02-05T12:00:44.399Z',
|
|
7
|
+
standfirst: null,
|
|
8
|
+
topper: {
|
|
9
|
+
__typename: 'TopperWithFlourish',
|
|
10
|
+
layout: 'flourish',
|
|
11
|
+
layoutWidth: 'full-width',
|
|
12
|
+
headline: 'News updates from February 2: US adds 353,000 jobs in January, US hits Iraq and Syria after drone deaths',
|
|
13
|
+
backgroundColour: 'paper',
|
|
14
|
+
backgroundBox: null,
|
|
15
|
+
textShadow: null,
|
|
16
|
+
followButtonVariant: 'standard',
|
|
17
|
+
intro: {
|
|
18
|
+
source: 'standfirst',
|
|
19
|
+
structured: {
|
|
20
|
+
tree: {
|
|
21
|
+
type: 'body',
|
|
22
|
+
version: 1,
|
|
23
|
+
children: [
|
|
24
|
+
{
|
|
25
|
+
type: 'text',
|
|
26
|
+
value: 'Media sector scrambles to deal with fallout from phase out of cross-website trackers '
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
displayConcept: {
|
|
33
|
+
id: '84cf4073-a674-4a93-aef9-dcc1832a65cb',
|
|
34
|
+
prefLabel: 'Amazon.com',
|
|
35
|
+
types: [
|
|
36
|
+
'http://www.ft.com/ontology/core/Thing',
|
|
37
|
+
'http://www.ft.com/ontology/concept/Concept',
|
|
38
|
+
'http://www.ft.com/ontology/organisation/Organisation',
|
|
39
|
+
'http://www.ft.com/ontology/company/Company',
|
|
40
|
+
'http://www.ft.com/ontology/company/PublicCompany'
|
|
41
|
+
],
|
|
42
|
+
type: 'ORGANISATION',
|
|
43
|
+
directType: 'http://www.ft.com/ontology/company/PublicCompany',
|
|
44
|
+
isPackageBrand: false,
|
|
45
|
+
predicate: 'http://www.ft.com/ontology/hasDisplayTag',
|
|
46
|
+
url: 'https://www.ft.com/stream/84cf4073-a674-4a93-aef9-dcc1832a65cb',
|
|
47
|
+
relativeUrl: '/stream/84cf4073-a674-4a93-aef9-dcc1832a65cb'
|
|
48
|
+
},
|
|
49
|
+
genreConcept: {
|
|
50
|
+
id: 'a579350c-61ce-4c00-97ca-ddaa2e0cacf6',
|
|
51
|
+
prefLabel: 'News',
|
|
52
|
+
types: [
|
|
53
|
+
'http://www.ft.com/ontology/core/Thing',
|
|
54
|
+
'http://www.ft.com/ontology/concept/Concept',
|
|
55
|
+
'http://www.ft.com/ontology/classification/Classification',
|
|
56
|
+
'http://www.ft.com/ontology/Genre'
|
|
57
|
+
],
|
|
58
|
+
type: 'GENRE',
|
|
59
|
+
directType: 'http://www.ft.com/ontology/Genre',
|
|
60
|
+
isPackageBrand: false,
|
|
61
|
+
predicate: 'http://www.ft.com/ontology/classification/isClassifiedBy',
|
|
62
|
+
url: 'https://www.ft.com/stream/a579350c-61ce-4c00-97ca-ddaa2e0cacf6',
|
|
63
|
+
relativeUrl: '/stream/a579350c-61ce-4c00-97ca-ddaa2e0cacf6'
|
|
64
|
+
},
|
|
65
|
+
leadFlourish: {
|
|
66
|
+
type: 'visualisation',
|
|
67
|
+
id: '15700475',
|
|
68
|
+
description: 'EU Airlines',
|
|
69
|
+
fallbackImage: {
|
|
70
|
+
url: 'https://www.ft.com/__origami/service/image/v2/images/raw/https%3A%2F%2Fpublic.flourish.studio%2Fvisualisation%2F15700475%2Fthumbnail?source=cp-content-pipeline&fit=scale-down&quality=highest&width=1020&dpr=1',
|
|
71
|
+
type: 'visualisation',
|
|
72
|
+
format: 'standard',
|
|
73
|
+
width: 1020,
|
|
74
|
+
height: 892
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
}
|