@financial-times/cp-content-pipeline-ui 9.12.1 → 9.14.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 +40 -0
- package/lib/components/ContentLayout/index.d.ts +25 -0
- package/lib/components/ContentLayout/index.js +34 -0
- package/lib/components/ContentLayout/index.js.map +1 -0
- package/lib/components/ContentLayout/test/index.spec.d.ts +1 -0
- package/lib/components/ContentLayout/test/index.spec.js +57 -0
- package/lib/components/ContentLayout/test/index.spec.js.map +1 -0
- package/lib/components/ContentLayout/test/snapshot.spec.d.ts +1 -0
- package/lib/components/ContentLayout/test/snapshot.spec.js +33 -0
- package/lib/components/ContentLayout/test/snapshot.spec.js.map +1 -0
- package/lib/components/RichText/index.js +4 -0
- package/lib/components/RichText/index.js.map +1 -1
- package/lib/components/content-tree/Clip/components/index.d.ts +0 -2
- package/lib/components/content-tree/Clip/components/index.js +1 -5
- package/lib/components/content-tree/Clip/components/index.js.map +1 -1
- package/lib/components/content-tree/Clip/template/component.d.ts +1 -1
- package/lib/components/content-tree/Clip/template/component.js +3 -3
- package/lib/components/content-tree/Clip/template/component.js.map +1 -1
- package/lib/components/content-tree/Clip/test/snapshot.spec.js +26 -0
- package/lib/components/content-tree/Clip/test/snapshot.spec.js.map +1 -1
- package/lib/components/content-tree/Timeline/TimelineEvent.d.ts +7 -0
- package/lib/components/content-tree/Timeline/TimelineEvent.js +17 -0
- package/lib/components/content-tree/Timeline/TimelineEvent.js.map +1 -0
- package/lib/components/content-tree/Timeline/index.d.ts +6 -0
- package/lib/components/content-tree/Timeline/index.js +17 -0
- package/lib/components/content-tree/Timeline/index.js.map +1 -0
- package/lib/components/content-tree/Timeline/test/TimelineEvent.spec.d.ts +1 -0
- package/lib/components/content-tree/Timeline/test/TimelineEvent.spec.js +48 -0
- package/lib/components/content-tree/Timeline/test/TimelineEvent.spec.js.map +1 -0
- package/lib/components/content-tree/Timeline/test/snapshot.spec.d.ts +1 -0
- package/lib/components/content-tree/Timeline/test/snapshot.spec.js +17 -0
- package/lib/components/content-tree/Timeline/test/snapshot.spec.js.map +1 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +5 -1
- package/lib/index.js.map +1 -1
- package/lib/main.scss +1 -0
- package/package.json +6 -6
- package/src/components/ContentLayout/index.tsx +87 -0
- package/src/components/ContentLayout/test/__snapshots__/index.spec.tsx.snap +96 -0
- package/src/components/ContentLayout/test/__snapshots__/snapshot.spec.tsx.snap +80 -0
- package/src/components/ContentLayout/test/index.spec.tsx +81 -0
- package/src/components/ContentLayout/test/snapshot.spec.tsx +47 -0
- package/src/components/RichText/index.tsx +4 -0
- package/src/components/content-tree/Clip/components/index.tsx +0 -2
- package/src/components/content-tree/Clip/template/component.tsx +23 -24
- package/src/components/content-tree/Clip/test/__snapshots__/snapshot.spec.tsx.snap +277 -0
- package/src/components/content-tree/Clip/test/snapshot.spec.tsx +40 -0
- package/src/components/content-tree/Timeline/TimelineEvent.tsx +25 -0
- package/src/components/content-tree/Timeline/client/main.scss +55 -0
- package/src/components/content-tree/Timeline/index.tsx +19 -0
- package/src/components/content-tree/Timeline/test/TimelineEvent.spec.tsx +66 -0
- package/src/components/content-tree/Timeline/test/__snapshots__/TimelineEvent.spec.tsx.snap +94 -0
- package/src/components/content-tree/Timeline/test/__snapshots__/snapshot.spec.tsx.snap +20 -0
- package/src/components/content-tree/Timeline/test/snapshot.spec.tsx +15 -0
- package/src/index.ts +2 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/lib/components/content-tree/Clip/components/Container.d.ts +0 -6
- package/lib/components/content-tree/Clip/components/Container.js +0 -13
- package/lib/components/content-tree/Clip/components/Container.js.map +0 -1
- package/lib/components/content-tree/Clip/components/ContentLayout.d.ts +0 -6
- package/lib/components/content-tree/Clip/components/ContentLayout.js +0 -13
- package/lib/components/content-tree/Clip/components/ContentLayout.js.map +0 -1
- package/src/components/content-tree/Clip/components/Container.tsx +0 -32
- package/src/components/content-tree/Clip/components/ContentLayout.tsx +0 -18
|
@@ -1,5 +1,282 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
|
+
exports[`Clip Snapshot component rendered on server ContentLayout integration tests edge case: custom dataLayout value should wrap in ContentLayout 1`] = `
|
|
4
|
+
"<div class="n-content-layout__container--in-line" data-component="clip-set">
|
|
5
|
+
<div
|
|
6
|
+
data-cp-clip-layout="custom-layout"
|
|
7
|
+
data-cp-clip-poster=""
|
|
8
|
+
data-cp-clip-no-audio="false"
|
|
9
|
+
data-cp-clip-no-description="false"
|
|
10
|
+
data-cp-clip-caption=""
|
|
11
|
+
data-cp-clip-no-info-box="false"
|
|
12
|
+
data-cp-clip-no-caption="false"
|
|
13
|
+
data-cp-clip-closed-caption="false"
|
|
14
|
+
class="cp-clip"
|
|
15
|
+
data-trackable="next-article-cp-clip"
|
|
16
|
+
data-o-component="cp-clip"
|
|
17
|
+
data-cp-clip-id="localhost:8080/fakevideo.mpg"
|
|
18
|
+
data-cp-clip-system-title=""
|
|
19
|
+
id=""
|
|
20
|
+
>
|
|
21
|
+
<div
|
|
22
|
+
data-o-component="o-expander"
|
|
23
|
+
class="o-expander o-expander__info-box"
|
|
24
|
+
data-o-expander-shrink-to="hidden"
|
|
25
|
+
data-trackable="clip-info-box"
|
|
26
|
+
data-o-expander-collapsed-toggle-text="<span class='o-expander__visually-hidden'>Show video info</span>"
|
|
27
|
+
data-o-expander-expanded-toggle-text="<span class='o-expander__visually-hidden'>Hide video info</span>"
|
|
28
|
+
>
|
|
29
|
+
<button
|
|
30
|
+
data-trackable="toggle-open-close"
|
|
31
|
+
class="o-expander__toggle o-expander__toggle-empty"
|
|
32
|
+
>
|
|
33
|
+
<span class="o-expander__visually-hidden o3-type-detail"
|
|
34
|
+
>Show video info</span
|
|
35
|
+
>
|
|
36
|
+
</button>
|
|
37
|
+
<div class="o-expander__content video-info"></div>
|
|
38
|
+
</div>
|
|
39
|
+
<div class="cp-clip__video-container">
|
|
40
|
+
<video
|
|
41
|
+
class="cp-clip__video"
|
|
42
|
+
controls=""
|
|
43
|
+
controlsList="nodownload noremoteplayback noplaybackrate"
|
|
44
|
+
disablepictureinpicture=""
|
|
45
|
+
disableremoteplayback=""
|
|
46
|
+
playsinline=""
|
|
47
|
+
poster=""
|
|
48
|
+
preload="auto"
|
|
49
|
+
id="clip-localhost:8080/fakevideo.mpg"
|
|
50
|
+
crossorigin="anonymous"
|
|
51
|
+
style="height: fit-content; width: 100%"
|
|
52
|
+
>
|
|
53
|
+
<source
|
|
54
|
+
id="video-source-0-localhost:8080/fakevideo.mpg"
|
|
55
|
+
data-cp-component="cp-clip__video-source"
|
|
56
|
+
src="localhost:8080/fakevideo.mpg"
|
|
57
|
+
type="video/mp4"
|
|
58
|
+
/>
|
|
59
|
+
</video>
|
|
60
|
+
</div>
|
|
61
|
+
<div
|
|
62
|
+
class="cp-clip__video-meta-info"
|
|
63
|
+
data-cp-clip-video-meta-info="true"
|
|
64
|
+
></div>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
"
|
|
68
|
+
`;
|
|
69
|
+
|
|
70
|
+
exports[`Clip Snapshot component rendered on server ContentLayout integration tests full-grid default render - should wrap in ContentLayout with proper classes 1`] = `
|
|
71
|
+
"<div class="n-content-layout" data-layout-width="full-grid">
|
|
72
|
+
<div class="n-content-layout__container" data-component="clip-set">
|
|
73
|
+
<div
|
|
74
|
+
data-cp-clip-layout="full-grid"
|
|
75
|
+
data-cp-clip-poster=""
|
|
76
|
+
data-cp-clip-no-audio="false"
|
|
77
|
+
data-cp-clip-no-description="false"
|
|
78
|
+
data-cp-clip-caption=""
|
|
79
|
+
data-cp-clip-no-info-box="false"
|
|
80
|
+
data-cp-clip-no-caption="false"
|
|
81
|
+
data-cp-clip-closed-caption="false"
|
|
82
|
+
class="cp-clip"
|
|
83
|
+
data-trackable="next-article-cp-clip"
|
|
84
|
+
data-o-component="cp-clip"
|
|
85
|
+
data-cp-clip-id="localhost:8080/fakevideo.mpg"
|
|
86
|
+
data-cp-clip-system-title=""
|
|
87
|
+
id=""
|
|
88
|
+
>
|
|
89
|
+
<div
|
|
90
|
+
data-o-component="o-expander"
|
|
91
|
+
class="o-expander o-expander__info-box"
|
|
92
|
+
data-o-expander-shrink-to="hidden"
|
|
93
|
+
data-trackable="clip-info-box"
|
|
94
|
+
data-o-expander-collapsed-toggle-text="<span class='o-expander__visually-hidden'>Show video info</span>"
|
|
95
|
+
data-o-expander-expanded-toggle-text="<span class='o-expander__visually-hidden'>Hide video info</span>"
|
|
96
|
+
>
|
|
97
|
+
<button
|
|
98
|
+
data-trackable="toggle-open-close"
|
|
99
|
+
class="o-expander__toggle o-expander__toggle-empty"
|
|
100
|
+
>
|
|
101
|
+
<span class="o-expander__visually-hidden o3-type-detail"
|
|
102
|
+
>Show video info</span
|
|
103
|
+
>
|
|
104
|
+
</button>
|
|
105
|
+
<div class="o-expander__content video-info"></div>
|
|
106
|
+
</div>
|
|
107
|
+
<div class="cp-clip__video-container">
|
|
108
|
+
<video
|
|
109
|
+
class="cp-clip__video"
|
|
110
|
+
controls=""
|
|
111
|
+
controlsList="nodownload noremoteplayback noplaybackrate"
|
|
112
|
+
disablepictureinpicture=""
|
|
113
|
+
disableremoteplayback=""
|
|
114
|
+
playsinline=""
|
|
115
|
+
poster=""
|
|
116
|
+
preload="auto"
|
|
117
|
+
id="clip-localhost:8080/fakevideo.mpg"
|
|
118
|
+
crossorigin="anonymous"
|
|
119
|
+
style="height: fit-content; width: 100%"
|
|
120
|
+
>
|
|
121
|
+
<source
|
|
122
|
+
id="video-source-0-localhost:8080/fakevideo.mpg"
|
|
123
|
+
data-cp-component="cp-clip__video-source"
|
|
124
|
+
src="localhost:8080/fakevideo.mpg"
|
|
125
|
+
type="video/mp4"
|
|
126
|
+
/>
|
|
127
|
+
</video>
|
|
128
|
+
</div>
|
|
129
|
+
<div
|
|
130
|
+
class="cp-clip__video-meta-info"
|
|
131
|
+
data-cp-clip-video-meta-info="true"
|
|
132
|
+
></div>
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
"
|
|
137
|
+
`;
|
|
138
|
+
|
|
139
|
+
exports[`Clip Snapshot component rendered on server ContentLayout integration tests in-line render - should not wrap in ContentLayout div 1`] = `
|
|
140
|
+
"<div class="n-content-layout__container--in-line" data-component="clip-set">
|
|
141
|
+
<div
|
|
142
|
+
data-cp-clip-layout="in-line"
|
|
143
|
+
data-cp-clip-poster=""
|
|
144
|
+
data-cp-clip-no-audio="false"
|
|
145
|
+
data-cp-clip-no-description="false"
|
|
146
|
+
data-cp-clip-caption=""
|
|
147
|
+
data-cp-clip-no-info-box="false"
|
|
148
|
+
data-cp-clip-no-caption="false"
|
|
149
|
+
data-cp-clip-closed-caption="false"
|
|
150
|
+
class="cp-clip"
|
|
151
|
+
data-trackable="next-article-cp-clip"
|
|
152
|
+
data-o-component="cp-clip"
|
|
153
|
+
data-cp-clip-id="localhost:8080/fakevideo.mpg"
|
|
154
|
+
data-cp-clip-system-title=""
|
|
155
|
+
id=""
|
|
156
|
+
>
|
|
157
|
+
<div
|
|
158
|
+
data-o-component="o-expander"
|
|
159
|
+
class="o-expander o-expander__info-box"
|
|
160
|
+
data-o-expander-shrink-to="hidden"
|
|
161
|
+
data-trackable="clip-info-box"
|
|
162
|
+
data-o-expander-collapsed-toggle-text="<span class='o-expander__visually-hidden'>Show video info</span>"
|
|
163
|
+
data-o-expander-expanded-toggle-text="<span class='o-expander__visually-hidden'>Hide video info</span>"
|
|
164
|
+
>
|
|
165
|
+
<button
|
|
166
|
+
data-trackable="toggle-open-close"
|
|
167
|
+
class="o-expander__toggle o-expander__toggle-empty"
|
|
168
|
+
>
|
|
169
|
+
<span class="o-expander__visually-hidden o3-type-detail"
|
|
170
|
+
>Show video info</span
|
|
171
|
+
>
|
|
172
|
+
</button>
|
|
173
|
+
<div class="o-expander__content video-info"></div>
|
|
174
|
+
</div>
|
|
175
|
+
<div class="cp-clip__video-container">
|
|
176
|
+
<video
|
|
177
|
+
class="cp-clip__video"
|
|
178
|
+
controls=""
|
|
179
|
+
controlsList="nodownload noremoteplayback noplaybackrate"
|
|
180
|
+
disablepictureinpicture=""
|
|
181
|
+
disableremoteplayback=""
|
|
182
|
+
playsinline=""
|
|
183
|
+
poster=""
|
|
184
|
+
preload="auto"
|
|
185
|
+
id="clip-localhost:8080/fakevideo.mpg"
|
|
186
|
+
crossorigin="anonymous"
|
|
187
|
+
style="height: fit-content; width: 100%"
|
|
188
|
+
>
|
|
189
|
+
<source
|
|
190
|
+
id="video-source-0-localhost:8080/fakevideo.mpg"
|
|
191
|
+
data-cp-component="cp-clip__video-source"
|
|
192
|
+
src="localhost:8080/fakevideo.mpg"
|
|
193
|
+
type="video/mp4"
|
|
194
|
+
/>
|
|
195
|
+
</video>
|
|
196
|
+
</div>
|
|
197
|
+
<div
|
|
198
|
+
class="cp-clip__video-meta-info"
|
|
199
|
+
data-cp-clip-video-meta-info="true"
|
|
200
|
+
></div>
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
"
|
|
204
|
+
`;
|
|
205
|
+
|
|
206
|
+
exports[`Clip Snapshot component rendered on server ContentLayout integration tests mid-grid default render - should wrap in ContentLayout with nested Container structure 1`] = `
|
|
207
|
+
"<div class="n-content-layout" data-layout-width="full-grid">
|
|
208
|
+
<div class="n-content-layout__container" data-component="clip-set">
|
|
209
|
+
<div
|
|
210
|
+
data-o-grid-colspan="12 S12 M12 L10 XL10"
|
|
211
|
+
class="n-content-layout__container--mid-grid"
|
|
212
|
+
>
|
|
213
|
+
<div
|
|
214
|
+
data-cp-clip-layout="mid-grid"
|
|
215
|
+
data-cp-clip-poster=""
|
|
216
|
+
data-cp-clip-no-audio="false"
|
|
217
|
+
data-cp-clip-no-description="false"
|
|
218
|
+
data-cp-clip-caption=""
|
|
219
|
+
data-cp-clip-no-info-box="false"
|
|
220
|
+
data-cp-clip-no-caption="false"
|
|
221
|
+
data-cp-clip-closed-caption="false"
|
|
222
|
+
class="cp-clip"
|
|
223
|
+
data-trackable="next-article-cp-clip"
|
|
224
|
+
data-o-component="cp-clip"
|
|
225
|
+
data-cp-clip-id="localhost:8080/fakevideo.mpg"
|
|
226
|
+
data-cp-clip-system-title=""
|
|
227
|
+
id=""
|
|
228
|
+
>
|
|
229
|
+
<div
|
|
230
|
+
data-o-component="o-expander"
|
|
231
|
+
class="o-expander o-expander__info-box"
|
|
232
|
+
data-o-expander-shrink-to="hidden"
|
|
233
|
+
data-trackable="clip-info-box"
|
|
234
|
+
data-o-expander-collapsed-toggle-text="<span class='o-expander__visually-hidden'>Show video info</span>"
|
|
235
|
+
data-o-expander-expanded-toggle-text="<span class='o-expander__visually-hidden'>Hide video info</span>"
|
|
236
|
+
>
|
|
237
|
+
<button
|
|
238
|
+
data-trackable="toggle-open-close"
|
|
239
|
+
class="o-expander__toggle o-expander__toggle-empty"
|
|
240
|
+
>
|
|
241
|
+
<span class="o-expander__visually-hidden o3-type-detail"
|
|
242
|
+
>Show video info</span
|
|
243
|
+
>
|
|
244
|
+
</button>
|
|
245
|
+
<div class="o-expander__content video-info"></div>
|
|
246
|
+
</div>
|
|
247
|
+
<div class="cp-clip__video-container">
|
|
248
|
+
<video
|
|
249
|
+
class="cp-clip__video"
|
|
250
|
+
controls=""
|
|
251
|
+
controlsList="nodownload noremoteplayback noplaybackrate"
|
|
252
|
+
disablepictureinpicture=""
|
|
253
|
+
disableremoteplayback=""
|
|
254
|
+
playsinline=""
|
|
255
|
+
poster=""
|
|
256
|
+
preload="auto"
|
|
257
|
+
id="clip-localhost:8080/fakevideo.mpg"
|
|
258
|
+
crossorigin="anonymous"
|
|
259
|
+
style="height: fit-content; width: 100%"
|
|
260
|
+
>
|
|
261
|
+
<source
|
|
262
|
+
id="video-source-0-localhost:8080/fakevideo.mpg"
|
|
263
|
+
data-cp-component="cp-clip__video-source"
|
|
264
|
+
src="localhost:8080/fakevideo.mpg"
|
|
265
|
+
type="video/mp4"
|
|
266
|
+
/>
|
|
267
|
+
</video>
|
|
268
|
+
</div>
|
|
269
|
+
<div
|
|
270
|
+
class="cp-clip__video-meta-info"
|
|
271
|
+
data-cp-clip-video-meta-info="true"
|
|
272
|
+
></div>
|
|
273
|
+
</div>
|
|
274
|
+
</div>
|
|
275
|
+
</div>
|
|
276
|
+
</div>
|
|
277
|
+
"
|
|
278
|
+
`;
|
|
279
|
+
|
|
3
280
|
exports[`Clip Snapshot component rendered on server full-grid default render 1`] = `
|
|
4
281
|
"<div class="n-content-layout" data-layout-width="full-grid">
|
|
5
282
|
<div class="n-content-layout__container" data-component="clip-set">
|
|
@@ -25,6 +25,46 @@ describe('Clip Snapshot', () => {
|
|
|
25
25
|
const url = 'localhost:8080/fakevideo.mpg'
|
|
26
26
|
const poster = 'localhost:8080/fakeposter.jpg'
|
|
27
27
|
|
|
28
|
+
describe('ContentLayout integration tests', () => {
|
|
29
|
+
it('in-line render - should not wrap in ContentLayout div', () => {
|
|
30
|
+
const tree = renderer
|
|
31
|
+
.create(
|
|
32
|
+
<ClipServer content={{ url, dataLayout: 'in-line' }}></ClipServer>
|
|
33
|
+
)
|
|
34
|
+
.toJSON()
|
|
35
|
+
expect(formatString(tree)).toMatchSnapshot()
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it('full-grid default render - should wrap in ContentLayout with proper classes', () => {
|
|
39
|
+
const tree = renderer
|
|
40
|
+
.create(
|
|
41
|
+
<ClipServer content={{ url, dataLayout: 'full-grid' }}></ClipServer>
|
|
42
|
+
)
|
|
43
|
+
.toJSON()
|
|
44
|
+
expect(formatString(tree)).toMatchSnapshot()
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it('mid-grid default render - should wrap in ContentLayout with nested Container structure', () => {
|
|
48
|
+
const tree = renderer
|
|
49
|
+
.create(
|
|
50
|
+
<ClipServer content={{ url, dataLayout: 'mid-grid' }}></ClipServer>
|
|
51
|
+
)
|
|
52
|
+
.toJSON()
|
|
53
|
+
expect(formatString(tree)).toMatchSnapshot()
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('edge case: custom dataLayout value should wrap in ContentLayout', () => {
|
|
57
|
+
const tree = renderer
|
|
58
|
+
.create(
|
|
59
|
+
<ClipServer
|
|
60
|
+
content={{ url, dataLayout: 'custom-layout' }}
|
|
61
|
+
></ClipServer>
|
|
62
|
+
)
|
|
63
|
+
.toJSON()
|
|
64
|
+
expect(formatString(tree)).toMatchSnapshot()
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
|
+
|
|
28
68
|
it('in-line render', () => {
|
|
29
69
|
const tree = renderer
|
|
30
70
|
.create(
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ContentTree } from '@financial-times/content-tree'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import { ContentProps } from '../../types'
|
|
4
|
+
|
|
5
|
+
interface TimelineEventProps
|
|
6
|
+
extends ContentProps<Omit<ContentTree.TimelineEvent, 'children'>> {}
|
|
7
|
+
|
|
8
|
+
/*
|
|
9
|
+
* @description Event component is used to render a single event.
|
|
10
|
+
*/
|
|
11
|
+
const TimelineEvent: React.FC<React.PropsWithChildren<TimelineEventProps>> = ({
|
|
12
|
+
content: { title },
|
|
13
|
+
children,
|
|
14
|
+
}) => {
|
|
15
|
+
return (
|
|
16
|
+
<div className="cp-timeline-event">
|
|
17
|
+
<h5 className="cp-timeline-event__heading o3-type-label">
|
|
18
|
+
<span className="cp-timeline-event__heading-title">{title}</span>
|
|
19
|
+
</h5>
|
|
20
|
+
{children}
|
|
21
|
+
</div>
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export default TimelineEvent
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
@import "@financial-times/o3-foundation/css/core.css";
|
|
2
|
+
|
|
3
|
+
.cp-timeline {
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
|
|
7
|
+
.cp-timeline-event {
|
|
8
|
+
flex-basis: 100%;
|
|
9
|
+
padding-left: var(--o3-spacing-s);
|
|
10
|
+
margin-left: 0;
|
|
11
|
+
margin-top: 0;
|
|
12
|
+
margin-bottom: 0;
|
|
13
|
+
position: relative;
|
|
14
|
+
|
|
15
|
+
&::before {
|
|
16
|
+
content: "";
|
|
17
|
+
width: 2px;
|
|
18
|
+
background: var(--o3-color-palette-black);
|
|
19
|
+
height: 100%;
|
|
20
|
+
display: block;
|
|
21
|
+
position: absolute;
|
|
22
|
+
left: var(--o3-spacing-5xs);
|
|
23
|
+
top: 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.cp-timeline-event__heading {
|
|
27
|
+
position: relative;
|
|
28
|
+
margin-top: var(--o3-spacing-s);
|
|
29
|
+
margin-bottom: var(--o3-spacing-5xs);
|
|
30
|
+
|
|
31
|
+
.cp-timeline-event__heading-title {
|
|
32
|
+
font-weight: var(--o3-font-weight-semibold);
|
|
33
|
+
&::before {
|
|
34
|
+
content: "";
|
|
35
|
+
position: absolute;
|
|
36
|
+
top: 6px;
|
|
37
|
+
left: -23px;
|
|
38
|
+
height: var(--o3-spacing-4xs);
|
|
39
|
+
width: var(--o3-spacing-4xs);
|
|
40
|
+
border-radius: 50%;
|
|
41
|
+
background-color: var(--o3-color-palette-black);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
p {
|
|
47
|
+
margin-bottom: var(--o3-spacing-4xs);
|
|
48
|
+
margin-top: var(--o3-spacing-5xs);
|
|
49
|
+
font-family: var(--o3-type-body-base-font-family);
|
|
50
|
+
font-size: var(--o3-type-body-base-font-size);
|
|
51
|
+
font-weight: var(--o3-type-body-base-font-weight);
|
|
52
|
+
line-height: var(--o3-type-body-base-line-height);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { ContentLayout } from '../../ContentLayout'
|
|
3
|
+
|
|
4
|
+
interface TimelineProps {
|
|
5
|
+
children?: React.ReactNode
|
|
6
|
+
}
|
|
7
|
+
/*
|
|
8
|
+
* @description Timeline component is used to render a simple timeline of events.
|
|
9
|
+
* @param children - The content to be displayed in the layout.
|
|
10
|
+
*/
|
|
11
|
+
const Timeline: React.FC<TimelineProps> = ({ children }) => {
|
|
12
|
+
return (
|
|
13
|
+
<ContentLayout>
|
|
14
|
+
<div className="cp-timeline">{children}</div>
|
|
15
|
+
</ContentLayout>
|
|
16
|
+
)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default Timeline
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render } from '@testing-library/react'
|
|
3
|
+
import TimelineEvent from '../TimelineEvent'
|
|
4
|
+
|
|
5
|
+
describe('TimelineEvent', () => {
|
|
6
|
+
it('renders with date label and children', () => {
|
|
7
|
+
const { container } = render(
|
|
8
|
+
<TimelineEvent
|
|
9
|
+
content={{
|
|
10
|
+
type: 'timeline-event',
|
|
11
|
+
title: 'Significant Event',
|
|
12
|
+
}}
|
|
13
|
+
>
|
|
14
|
+
<p>This is the event content</p>
|
|
15
|
+
</TimelineEvent>
|
|
16
|
+
)
|
|
17
|
+
expect(container).toMatchSnapshot()
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
it('renders with minimal children content', () => {
|
|
21
|
+
const { container } = render(
|
|
22
|
+
<TimelineEvent
|
|
23
|
+
content={{
|
|
24
|
+
type: 'timeline-event',
|
|
25
|
+
title: 'Short Event',
|
|
26
|
+
}}
|
|
27
|
+
>
|
|
28
|
+
<p>Brief event description</p>
|
|
29
|
+
</TimelineEvent>
|
|
30
|
+
)
|
|
31
|
+
expect(container).toMatchSnapshot()
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('renders with long date label', () => {
|
|
35
|
+
const { container } = render(
|
|
36
|
+
<TimelineEvent
|
|
37
|
+
content={{
|
|
38
|
+
type: 'timeline-event',
|
|
39
|
+
title: 'Wednesday, December 25, 2024 - Christmas Day',
|
|
40
|
+
}}
|
|
41
|
+
>
|
|
42
|
+
<p>Christmas celebration details</p>
|
|
43
|
+
</TimelineEvent>
|
|
44
|
+
)
|
|
45
|
+
expect(container).toMatchSnapshot()
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it('renders with complex nested children', () => {
|
|
49
|
+
const { container } = render(
|
|
50
|
+
<TimelineEvent
|
|
51
|
+
content={{
|
|
52
|
+
type: 'timeline-event',
|
|
53
|
+
title: 'Q4 2024',
|
|
54
|
+
}}
|
|
55
|
+
>
|
|
56
|
+
<div>
|
|
57
|
+
<h3>Quarterly Results</h3>
|
|
58
|
+
<p>
|
|
59
|
+
The company announced <strong>strong</strong> Q4 results.
|
|
60
|
+
</p>
|
|
61
|
+
</div>
|
|
62
|
+
</TimelineEvent>
|
|
63
|
+
)
|
|
64
|
+
expect(container).toMatchSnapshot()
|
|
65
|
+
})
|
|
66
|
+
})
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`TimelineEvent renders with complex nested children 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="cp-timeline-event"
|
|
7
|
+
>
|
|
8
|
+
<h5
|
|
9
|
+
class="cp-timeline-event__heading o3-type-label"
|
|
10
|
+
>
|
|
11
|
+
<span
|
|
12
|
+
class="cp-timeline-event__heading-title"
|
|
13
|
+
>
|
|
14
|
+
Q4 2024
|
|
15
|
+
</span>
|
|
16
|
+
</h5>
|
|
17
|
+
<div>
|
|
18
|
+
<h3>
|
|
19
|
+
Quarterly Results
|
|
20
|
+
</h3>
|
|
21
|
+
<p>
|
|
22
|
+
The company announced
|
|
23
|
+
<strong>
|
|
24
|
+
strong
|
|
25
|
+
</strong>
|
|
26
|
+
Q4 results.
|
|
27
|
+
</p>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
`;
|
|
32
|
+
|
|
33
|
+
exports[`TimelineEvent renders with date label and children 1`] = `
|
|
34
|
+
<div>
|
|
35
|
+
<div
|
|
36
|
+
class="cp-timeline-event"
|
|
37
|
+
>
|
|
38
|
+
<h5
|
|
39
|
+
class="cp-timeline-event__heading o3-type-label"
|
|
40
|
+
>
|
|
41
|
+
<span
|
|
42
|
+
class="cp-timeline-event__heading-title"
|
|
43
|
+
>
|
|
44
|
+
Significant Event
|
|
45
|
+
</span>
|
|
46
|
+
</h5>
|
|
47
|
+
<p>
|
|
48
|
+
This is the event content
|
|
49
|
+
</p>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
`;
|
|
53
|
+
|
|
54
|
+
exports[`TimelineEvent renders with long date label 1`] = `
|
|
55
|
+
<div>
|
|
56
|
+
<div
|
|
57
|
+
class="cp-timeline-event"
|
|
58
|
+
>
|
|
59
|
+
<h5
|
|
60
|
+
class="cp-timeline-event__heading o3-type-label"
|
|
61
|
+
>
|
|
62
|
+
<span
|
|
63
|
+
class="cp-timeline-event__heading-title"
|
|
64
|
+
>
|
|
65
|
+
Wednesday, December 25, 2024 - Christmas Day
|
|
66
|
+
</span>
|
|
67
|
+
</h5>
|
|
68
|
+
<p>
|
|
69
|
+
Christmas celebration details
|
|
70
|
+
</p>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
`;
|
|
74
|
+
|
|
75
|
+
exports[`TimelineEvent renders with minimal children content 1`] = `
|
|
76
|
+
<div>
|
|
77
|
+
<div
|
|
78
|
+
class="cp-timeline-event"
|
|
79
|
+
>
|
|
80
|
+
<h5
|
|
81
|
+
class="cp-timeline-event__heading o3-type-label"
|
|
82
|
+
>
|
|
83
|
+
<span
|
|
84
|
+
class="cp-timeline-event__heading-title"
|
|
85
|
+
>
|
|
86
|
+
Short Event
|
|
87
|
+
</span>
|
|
88
|
+
</h5>
|
|
89
|
+
<p>
|
|
90
|
+
Brief event description
|
|
91
|
+
</p>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
`;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`Timeline component renders with full-width layout and children 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="n-content-layout__container--in-line"
|
|
7
|
+
>
|
|
8
|
+
<div
|
|
9
|
+
class="cp-timeline"
|
|
10
|
+
>
|
|
11
|
+
<div>
|
|
12
|
+
Event 1
|
|
13
|
+
</div>
|
|
14
|
+
<div>
|
|
15
|
+
Event 2
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
`;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render } from '@testing-library/react'
|
|
3
|
+
import Timeline from '../'
|
|
4
|
+
|
|
5
|
+
describe('Timeline component', () => {
|
|
6
|
+
it('renders with full-width layout and children', () => {
|
|
7
|
+
const { container } = render(
|
|
8
|
+
<Timeline>
|
|
9
|
+
<div>Event 1</div>
|
|
10
|
+
<div>Event 2</div>
|
|
11
|
+
</Timeline>
|
|
12
|
+
)
|
|
13
|
+
expect(container).toMatchSnapshot()
|
|
14
|
+
})
|
|
15
|
+
})
|
package/src/index.ts
CHANGED
|
@@ -30,6 +30,8 @@ export { default as Table } from './components/content-tree/Table'
|
|
|
30
30
|
export { default as Tweet } from './components/content-tree/Tweet'
|
|
31
31
|
export { default as Video } from './components/content-tree/Video'
|
|
32
32
|
export { default as YoutubeVideo } from './components/content-tree/YoutubeVideo'
|
|
33
|
+
export { default as Timeline } from './components/content-tree/Timeline'
|
|
34
|
+
export { default as TimelineEvent } from './components/content-tree/Timeline/TimelineEvent'
|
|
33
35
|
export {
|
|
34
36
|
List,
|
|
35
37
|
ListItem,
|