@financial-times/x-teaser 18.2.1 → 19.0.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/Props.d.ts +2 -1
- package/__tests__/Status.test.jsx +30 -37
- package/dist/Teaser.cjs.js +13 -17
- package/dist/Teaser.es5.js +13 -17
- package/dist/Teaser.esm.js +13 -17
- package/package.json +2 -2
- package/readme.md +2 -2
- package/src/ExclusiveLabel.jsx +10 -0
- package/src/Status.jsx +3 -10
- package/src/concerns/presets.js +8 -8
- package/storybook/index.jsx +1 -1
- package/src/ScoopLabel.jsx +0 -10
package/Props.d.ts
CHANGED
|
@@ -31,7 +31,7 @@ export interface Features {
|
|
|
31
31
|
showTitle?: boolean
|
|
32
32
|
showStandfirst?: boolean
|
|
33
33
|
showPremiumLabel?: boolean
|
|
34
|
-
|
|
34
|
+
showExclusiveLabel?: boolean
|
|
35
35
|
showStatus?: boolean
|
|
36
36
|
showImage?: boolean
|
|
37
37
|
showHeadshot?: boolean
|
|
@@ -159,6 +159,7 @@ export interface Indicators {
|
|
|
159
159
|
isPodcast?: boolean
|
|
160
160
|
/** Methode packaging options */
|
|
161
161
|
isEditorsChoice?: boolean
|
|
162
|
+
/** Controls whether the Exclusive badge is displayed */
|
|
162
163
|
isExclusive?: boolean
|
|
163
164
|
isScoop?: boolean
|
|
164
165
|
}
|
|
@@ -2,7 +2,7 @@ const { h } = require('@financial-times/x-engine')
|
|
|
2
2
|
const { mount } = require('@financial-times/x-test-utils/enzyme')
|
|
3
3
|
|
|
4
4
|
import * as LiveBlogStatus from '../src/LiveBlogStatus'
|
|
5
|
-
import * as
|
|
5
|
+
import * as ExclusiveLabel from '../src/ExclusiveLabel'
|
|
6
6
|
import * as PremiumLabel from '../src/PremiumLabel'
|
|
7
7
|
import * as AlwaysShowTimestamp from '../src/AlwaysShowTimestamp'
|
|
8
8
|
import * as RelativeTime from '../src/RelativeTime'
|
|
@@ -11,9 +11,9 @@ import * as TimeStamp from '../src/TimeStamp'
|
|
|
11
11
|
const LiveBlogStatusSpy = jest
|
|
12
12
|
.spyOn(LiveBlogStatus, 'default')
|
|
13
13
|
.mockReturnValue(<div className="live-blog-status">LiveBlogStatus</div>)
|
|
14
|
-
const
|
|
15
|
-
.spyOn(
|
|
16
|
-
.mockReturnValue(<div className="
|
|
14
|
+
const ExclusiveLabelSpy = jest
|
|
15
|
+
.spyOn(ExclusiveLabel, 'default')
|
|
16
|
+
.mockReturnValue(<div className="exclusive-label">ExclusiveLabel</div>)
|
|
17
17
|
const PremiumLabelSpy = jest
|
|
18
18
|
.spyOn(PremiumLabel, 'default')
|
|
19
19
|
.mockReturnValue(<div className="premium-label">PremiumLabel</div>)
|
|
@@ -35,9 +35,9 @@ describe('Status - Display Logic', () => {
|
|
|
35
35
|
props = {
|
|
36
36
|
showStatus: true,
|
|
37
37
|
showPremiumLabel: true,
|
|
38
|
-
|
|
38
|
+
showExclusiveLabel: true,
|
|
39
39
|
status: 'inprogress',
|
|
40
|
-
indicators: {
|
|
40
|
+
indicators: { isExclusive: true, accessLevel: 'premium' },
|
|
41
41
|
firstPublishedDate: '2025-10-01T00:00:00.000Z',
|
|
42
42
|
publishedDate: '2025-10-01T00:00:00.000Z',
|
|
43
43
|
useRelativeTimeIfToday: true,
|
|
@@ -54,7 +54,7 @@ describe('Status - Display Logic', () => {
|
|
|
54
54
|
mount(<Status {...props} />)
|
|
55
55
|
|
|
56
56
|
expect(LiveBlogStatusSpy).toHaveBeenCalledTimes(1)
|
|
57
|
-
expect(
|
|
57
|
+
expect(ExclusiveLabelSpy).not.toHaveBeenCalled()
|
|
58
58
|
expect(PremiumLabelSpy).not.toHaveBeenCalled()
|
|
59
59
|
expect(AlwaysShowTimestampSpy).not.toHaveBeenCalled()
|
|
60
60
|
expect(RelativeTimeSpy).not.toHaveBeenCalled()
|
|
@@ -76,15 +76,15 @@ describe('Status - Display Logic', () => {
|
|
|
76
76
|
})
|
|
77
77
|
})
|
|
78
78
|
|
|
79
|
-
describe('
|
|
79
|
+
describe('ExclusiveLabel', () => {
|
|
80
80
|
beforeEach(() => {
|
|
81
81
|
delete props.status
|
|
82
82
|
})
|
|
83
83
|
|
|
84
|
-
it('renders only
|
|
84
|
+
it('renders only ExclusiveLabel when higher-level render props are absent and ExclusiveLabel props are present', () => {
|
|
85
85
|
mount(<Status {...props} />)
|
|
86
86
|
|
|
87
|
-
expect(
|
|
87
|
+
expect(ExclusiveLabelSpy).toHaveBeenCalledTimes(1)
|
|
88
88
|
expect(LiveBlogStatusSpy).not.toHaveBeenCalled()
|
|
89
89
|
expect(PremiumLabelSpy).not.toHaveBeenCalled()
|
|
90
90
|
expect(AlwaysShowTimestampSpy).not.toHaveBeenCalled()
|
|
@@ -92,32 +92,25 @@ describe('Status - Display Logic', () => {
|
|
|
92
92
|
expect(TimeStampSpy).not.toHaveBeenCalled()
|
|
93
93
|
})
|
|
94
94
|
|
|
95
|
-
it('should not render
|
|
96
|
-
props.
|
|
95
|
+
it('should not render ExclusiveLabel when showExclusiveLabel = false', () => {
|
|
96
|
+
props.showExclusiveLabel = false
|
|
97
97
|
mount(<Status {...props} />)
|
|
98
98
|
|
|
99
|
-
expect(
|
|
99
|
+
expect(ExclusiveLabelSpy).not.toHaveBeenCalled()
|
|
100
100
|
})
|
|
101
101
|
|
|
102
|
-
it('should not render
|
|
103
|
-
props.indicators.
|
|
102
|
+
it('should not render ExclusiveLabel when props.indicators.isExclusive = false', () => {
|
|
103
|
+
props.indicators.isExclusive = false
|
|
104
104
|
mount(<Status {...props} />)
|
|
105
105
|
|
|
106
|
-
expect(
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
it('should not render ScoopLabel when firstPublishedDate is older than the cutoff date', () => {
|
|
110
|
-
props.firstPublishedDate = '2025-09-01T00:00:00.000Z'
|
|
111
|
-
mount(<Status {...props} />)
|
|
112
|
-
|
|
113
|
-
expect(ScoopLabelSpy).not.toHaveBeenCalled()
|
|
106
|
+
expect(ExclusiveLabelSpy).not.toHaveBeenCalled()
|
|
114
107
|
})
|
|
115
108
|
})
|
|
116
109
|
|
|
117
110
|
describe('PremiumLabel', () => {
|
|
118
111
|
beforeEach(() => {
|
|
119
112
|
delete props.status
|
|
120
|
-
props.
|
|
113
|
+
props.showExclusiveLabel = false
|
|
121
114
|
})
|
|
122
115
|
|
|
123
116
|
it('renders only PremiumLabel when higher-level render props are absent and PremiumLabel props are present', () => {
|
|
@@ -125,7 +118,7 @@ describe('Status - Display Logic', () => {
|
|
|
125
118
|
|
|
126
119
|
expect(PremiumLabelSpy).toHaveBeenCalledTimes(1)
|
|
127
120
|
expect(LiveBlogStatusSpy).not.toHaveBeenCalled()
|
|
128
|
-
expect(
|
|
121
|
+
expect(ExclusiveLabelSpy).not.toHaveBeenCalled()
|
|
129
122
|
expect(AlwaysShowTimestampSpy).not.toHaveBeenCalled()
|
|
130
123
|
})
|
|
131
124
|
|
|
@@ -147,7 +140,7 @@ describe('Status - Display Logic', () => {
|
|
|
147
140
|
describe('AlwaysShowTimestamp', () => {
|
|
148
141
|
beforeEach(() => {
|
|
149
142
|
delete props.status
|
|
150
|
-
props.
|
|
143
|
+
props.showExclusiveLabel = false
|
|
151
144
|
props.showPremiumLabel = false
|
|
152
145
|
})
|
|
153
146
|
|
|
@@ -159,7 +152,7 @@ describe('Status - Display Logic', () => {
|
|
|
159
152
|
|
|
160
153
|
expect(AlwaysShowTimestampSpy).toHaveBeenCalledTimes(1)
|
|
161
154
|
expect(LiveBlogStatusSpy).not.toHaveBeenCalled()
|
|
162
|
-
expect(
|
|
155
|
+
expect(ExclusiveLabelSpy).not.toHaveBeenCalled()
|
|
163
156
|
expect(PremiumLabelSpy).not.toHaveBeenCalled()
|
|
164
157
|
expect(RelativeTimeSpy).not.toHaveBeenCalled()
|
|
165
158
|
expect(TimeStampSpy).not.toHaveBeenCalled()
|
|
@@ -211,7 +204,7 @@ describe('Status - Display Logic', () => {
|
|
|
211
204
|
describe('RelativeTime', () => {
|
|
212
205
|
beforeEach(() => {
|
|
213
206
|
delete props.status
|
|
214
|
-
props.
|
|
207
|
+
props.showExclusiveLabel = false
|
|
215
208
|
props.showPremiumLabel = false
|
|
216
209
|
props.useRelativeTimeIfToday = false
|
|
217
210
|
})
|
|
@@ -221,7 +214,7 @@ describe('Status - Display Logic', () => {
|
|
|
221
214
|
|
|
222
215
|
expect(RelativeTimeSpy).toHaveBeenCalledTimes(1)
|
|
223
216
|
expect(LiveBlogStatusSpy).not.toHaveBeenCalled()
|
|
224
|
-
expect(
|
|
217
|
+
expect(ExclusiveLabelSpy).not.toHaveBeenCalled()
|
|
225
218
|
expect(PremiumLabelSpy).not.toHaveBeenCalled()
|
|
226
219
|
expect(AlwaysShowTimestampSpy).not.toHaveBeenCalled()
|
|
227
220
|
expect(TimeStampSpy).not.toHaveBeenCalled()
|
|
@@ -252,7 +245,7 @@ describe('Status - Display Logic', () => {
|
|
|
252
245
|
describe('TimeStamp', () => {
|
|
253
246
|
beforeEach(() => {
|
|
254
247
|
delete props.status
|
|
255
|
-
props.
|
|
248
|
+
props.showExclusiveLabel = false
|
|
256
249
|
props.showPremiumLabel = false
|
|
257
250
|
props.useRelativeTimeIfToday = false
|
|
258
251
|
props.useRelativeTime = false
|
|
@@ -263,7 +256,7 @@ describe('Status - Display Logic', () => {
|
|
|
263
256
|
|
|
264
257
|
expect(TimeStampSpy).toHaveBeenCalledTimes(1)
|
|
265
258
|
expect(LiveBlogStatusSpy).not.toHaveBeenCalled()
|
|
266
|
-
expect(
|
|
259
|
+
expect(ExclusiveLabelSpy).not.toHaveBeenCalled()
|
|
267
260
|
expect(PremiumLabelSpy).not.toHaveBeenCalled()
|
|
268
261
|
expect(AlwaysShowTimestampSpy).not.toHaveBeenCalled()
|
|
269
262
|
expect(RelativeTimeSpy).not.toHaveBeenCalled()
|
|
@@ -289,9 +282,9 @@ describe('Status - Display Logic', () => {
|
|
|
289
282
|
props = {
|
|
290
283
|
showStatus: false,
|
|
291
284
|
showPremiumLabel: false,
|
|
292
|
-
|
|
285
|
+
showExclusiveLabel: false,
|
|
293
286
|
status: 'inprogress',
|
|
294
|
-
indicators: {
|
|
287
|
+
indicators: { isExclusive: true, accessLevel: 'premium' },
|
|
295
288
|
firstPublishedDate: '2025-10-01T00:00:00.000Z',
|
|
296
289
|
publishedDate: '2025-10-01T00:00:00.000Z',
|
|
297
290
|
useRelativeTimeIfToday: true,
|
|
@@ -301,7 +294,7 @@ describe('Status - Display Logic', () => {
|
|
|
301
294
|
|
|
302
295
|
expect(subject.isEmptyRender()).toBeTruthy()
|
|
303
296
|
expect(LiveBlogStatusSpy).not.toHaveBeenCalled()
|
|
304
|
-
expect(
|
|
297
|
+
expect(ExclusiveLabelSpy).not.toHaveBeenCalled()
|
|
305
298
|
expect(PremiumLabelSpy).not.toHaveBeenCalled()
|
|
306
299
|
expect(AlwaysShowTimestampSpy).not.toHaveBeenCalled()
|
|
307
300
|
expect(RelativeTimeSpy).not.toHaveBeenCalled()
|
|
@@ -313,8 +306,8 @@ describe('Status - Display Logic', () => {
|
|
|
313
306
|
props = {
|
|
314
307
|
showStatus: true,
|
|
315
308
|
showPremiumLabel: false,
|
|
316
|
-
|
|
317
|
-
indicators: {
|
|
309
|
+
showExclusiveLabel: false,
|
|
310
|
+
indicators: { isExclusive: true, accessLevel: 'premium' },
|
|
318
311
|
firstPublishedDate: '2025-10-01T00:00:00.000Z',
|
|
319
312
|
useRelativeTimeIfToday: true,
|
|
320
313
|
useRelativeTime: true
|
|
@@ -323,7 +316,7 @@ describe('Status - Display Logic', () => {
|
|
|
323
316
|
|
|
324
317
|
expect(subject.isEmptyRender()).toBeTruthy()
|
|
325
318
|
expect(LiveBlogStatusSpy).not.toHaveBeenCalled()
|
|
326
|
-
expect(
|
|
319
|
+
expect(ExclusiveLabelSpy).not.toHaveBeenCalled()
|
|
327
320
|
expect(PremiumLabelSpy).not.toHaveBeenCalled()
|
|
328
321
|
expect(AlwaysShowTimestampSpy).not.toHaveBeenCalled()
|
|
329
322
|
expect(RelativeTimeSpy).not.toHaveBeenCalled()
|
package/dist/Teaser.cjs.js
CHANGED
|
@@ -499,11 +499,11 @@ function PremiumLabel() {
|
|
|
499
499
|
);
|
|
500
500
|
}
|
|
501
501
|
|
|
502
|
-
function
|
|
502
|
+
function ExclusiveLabel() {
|
|
503
503
|
return xEngine.h("div", {
|
|
504
|
-
className: "o-teaser__labels o-teaser__labels--
|
|
504
|
+
className: "o-teaser__labels o-teaser__labels--exclusive"
|
|
505
505
|
}, xEngine.h("span", {
|
|
506
|
-
className: "o-labels o-labels--content-
|
|
506
|
+
className: "o-labels o-labels--content-exclusive"
|
|
507
507
|
}, "Exclusive"), xEngine.h("span", {
|
|
508
508
|
className: "o3-visually-hidden"
|
|
509
509
|
}, "\xA0content"));
|
|
@@ -514,12 +514,8 @@ var Status = props => {
|
|
|
514
514
|
if (props.showStatus && props.status) {
|
|
515
515
|
return xEngine.h(LiveBlogStatus, props);
|
|
516
516
|
}
|
|
517
|
-
if (props.
|
|
518
|
-
|
|
519
|
-
// If we later show it on other pages, this cutoff date will need review.
|
|
520
|
-
// The `isScoop` property already exists, but Editorial will use it differently after 2025-10-01.
|
|
521
|
-
new Date(props.firstPublishedDate) >= new Date('2025-10-01T00:00:00.000Z')) {
|
|
522
|
-
return xEngine.h(ScoopLabel, props);
|
|
517
|
+
if (props.showExclusiveLabel && props !== null && props !== void 0 && (_props$indicators = props.indicators) !== null && _props$indicators !== void 0 && _props$indicators.isExclusive) {
|
|
518
|
+
return xEngine.h(ExclusiveLabel, props);
|
|
523
519
|
}
|
|
524
520
|
if (props.showPremiumLabel && (props === null || props === void 0 || (_props$indicators2 = props.indicators) === null || _props$indicators2 === void 0 ? void 0 : _props$indicators2.accessLevel) === 'premium') {
|
|
525
521
|
return xEngine.h(PremiumLabel, props);
|
|
@@ -636,7 +632,7 @@ const Small = {
|
|
|
636
632
|
showMeta: true,
|
|
637
633
|
showTitle: true,
|
|
638
634
|
showPremiumLabel: true,
|
|
639
|
-
|
|
635
|
+
showExclusiveLabel: false,
|
|
640
636
|
showStatus: true
|
|
641
637
|
};
|
|
642
638
|
const SmallHeavy = {
|
|
@@ -646,7 +642,7 @@ const SmallHeavy = {
|
|
|
646
642
|
showTitle: true,
|
|
647
643
|
showStandfirst: true,
|
|
648
644
|
showPremiumLabel: true,
|
|
649
|
-
|
|
645
|
+
showExclusiveLabel: false,
|
|
650
646
|
showStatus: true,
|
|
651
647
|
showImage: true,
|
|
652
648
|
imageSize: 'Small'
|
|
@@ -658,7 +654,7 @@ const Large = {
|
|
|
658
654
|
showTitle: true,
|
|
659
655
|
showStandfirst: true,
|
|
660
656
|
showPremiumLabel: true,
|
|
661
|
-
|
|
657
|
+
showExclusiveLabel: false,
|
|
662
658
|
showStatus: true,
|
|
663
659
|
showImage: true,
|
|
664
660
|
imageSize: 'Medium'
|
|
@@ -669,7 +665,7 @@ const Hero = {
|
|
|
669
665
|
showMeta: true,
|
|
670
666
|
showTitle: true,
|
|
671
667
|
showPremiumLabel: true,
|
|
672
|
-
|
|
668
|
+
showExclusiveLabel: false,
|
|
673
669
|
showStatus: true,
|
|
674
670
|
showImage: true,
|
|
675
671
|
imageSize: 'Medium'
|
|
@@ -681,7 +677,7 @@ const HeroNarrow = {
|
|
|
681
677
|
showTitle: true,
|
|
682
678
|
showStandfirst: true,
|
|
683
679
|
showPremiumLabel: true,
|
|
684
|
-
|
|
680
|
+
showExclusiveLabel: false,
|
|
685
681
|
showStatus: true
|
|
686
682
|
};
|
|
687
683
|
const HeroVideo = {
|
|
@@ -698,7 +694,7 @@ const HeroOverlay = {
|
|
|
698
694
|
showMeta: true,
|
|
699
695
|
showTitle: true,
|
|
700
696
|
showPremiumLabel: true,
|
|
701
|
-
|
|
697
|
+
showExclusiveLabel: false,
|
|
702
698
|
showStatus: true,
|
|
703
699
|
showImage: true,
|
|
704
700
|
imageSize: 'XL',
|
|
@@ -711,7 +707,7 @@ const TopStory = {
|
|
|
711
707
|
showTitle: true,
|
|
712
708
|
showStandfirst: true,
|
|
713
709
|
showPremiumLabel: true,
|
|
714
|
-
|
|
710
|
+
showExclusiveLabel: false,
|
|
715
711
|
showStatus: true,
|
|
716
712
|
showRelatedLinks: true
|
|
717
713
|
};
|
|
@@ -722,7 +718,7 @@ const TopStoryLandscape = {
|
|
|
722
718
|
showTitle: true,
|
|
723
719
|
showStandfirst: true,
|
|
724
720
|
showPremiumLabel: true,
|
|
725
|
-
|
|
721
|
+
showExclusiveLabel: false,
|
|
726
722
|
showStatus: true,
|
|
727
723
|
showImage: true,
|
|
728
724
|
imageSize: 'XL',
|
package/dist/Teaser.es5.js
CHANGED
|
@@ -584,11 +584,11 @@ function PremiumLabel() {
|
|
|
584
584
|
);
|
|
585
585
|
}
|
|
586
586
|
|
|
587
|
-
function
|
|
587
|
+
function ExclusiveLabel() {
|
|
588
588
|
return xEngine.h("div", {
|
|
589
|
-
className: "o-teaser__labels o-teaser__labels--
|
|
589
|
+
className: "o-teaser__labels o-teaser__labels--exclusive"
|
|
590
590
|
}, xEngine.h("span", {
|
|
591
|
-
className: "o-labels o-labels--content-
|
|
591
|
+
className: "o-labels o-labels--content-exclusive"
|
|
592
592
|
}, "Exclusive"), xEngine.h("span", {
|
|
593
593
|
className: "o3-visually-hidden"
|
|
594
594
|
}, "\xA0content"));
|
|
@@ -599,12 +599,8 @@ var Status = (function (props) {
|
|
|
599
599
|
if (props.showStatus && props.status) {
|
|
600
600
|
return xEngine.h(LiveBlogStatus, props);
|
|
601
601
|
}
|
|
602
|
-
if (props.
|
|
603
|
-
|
|
604
|
-
// If we later show it on other pages, this cutoff date will need review.
|
|
605
|
-
// The `isScoop` property already exists, but Editorial will use it differently after 2025-10-01.
|
|
606
|
-
new Date(props.firstPublishedDate) >= new Date('2025-10-01T00:00:00.000Z')) {
|
|
607
|
-
return xEngine.h(ScoopLabel, props);
|
|
602
|
+
if (props.showExclusiveLabel && props !== null && props !== void 0 && (_props$indicators = props.indicators) !== null && _props$indicators !== void 0 && _props$indicators.isExclusive) {
|
|
603
|
+
return xEngine.h(ExclusiveLabel, props);
|
|
608
604
|
}
|
|
609
605
|
if (props.showPremiumLabel && (props === null || props === void 0 || (_props$indicators2 = props.indicators) === null || _props$indicators2 === void 0 ? void 0 : _props$indicators2.accessLevel) === 'premium') {
|
|
610
606
|
return xEngine.h(PremiumLabel, props);
|
|
@@ -726,7 +722,7 @@ var Small = {
|
|
|
726
722
|
showMeta: true,
|
|
727
723
|
showTitle: true,
|
|
728
724
|
showPremiumLabel: true,
|
|
729
|
-
|
|
725
|
+
showExclusiveLabel: false,
|
|
730
726
|
showStatus: true
|
|
731
727
|
};
|
|
732
728
|
var SmallHeavy = {
|
|
@@ -736,7 +732,7 @@ var SmallHeavy = {
|
|
|
736
732
|
showTitle: true,
|
|
737
733
|
showStandfirst: true,
|
|
738
734
|
showPremiumLabel: true,
|
|
739
|
-
|
|
735
|
+
showExclusiveLabel: false,
|
|
740
736
|
showStatus: true,
|
|
741
737
|
showImage: true,
|
|
742
738
|
imageSize: 'Small'
|
|
@@ -748,7 +744,7 @@ var Large = {
|
|
|
748
744
|
showTitle: true,
|
|
749
745
|
showStandfirst: true,
|
|
750
746
|
showPremiumLabel: true,
|
|
751
|
-
|
|
747
|
+
showExclusiveLabel: false,
|
|
752
748
|
showStatus: true,
|
|
753
749
|
showImage: true,
|
|
754
750
|
imageSize: 'Medium'
|
|
@@ -759,7 +755,7 @@ var Hero = {
|
|
|
759
755
|
showMeta: true,
|
|
760
756
|
showTitle: true,
|
|
761
757
|
showPremiumLabel: true,
|
|
762
|
-
|
|
758
|
+
showExclusiveLabel: false,
|
|
763
759
|
showStatus: true,
|
|
764
760
|
showImage: true,
|
|
765
761
|
imageSize: 'Medium'
|
|
@@ -771,7 +767,7 @@ var HeroNarrow = {
|
|
|
771
767
|
showTitle: true,
|
|
772
768
|
showStandfirst: true,
|
|
773
769
|
showPremiumLabel: true,
|
|
774
|
-
|
|
770
|
+
showExclusiveLabel: false,
|
|
775
771
|
showStatus: true
|
|
776
772
|
};
|
|
777
773
|
var HeroVideo = {
|
|
@@ -788,7 +784,7 @@ var HeroOverlay = {
|
|
|
788
784
|
showMeta: true,
|
|
789
785
|
showTitle: true,
|
|
790
786
|
showPremiumLabel: true,
|
|
791
|
-
|
|
787
|
+
showExclusiveLabel: false,
|
|
792
788
|
showStatus: true,
|
|
793
789
|
showImage: true,
|
|
794
790
|
imageSize: 'XL',
|
|
@@ -801,7 +797,7 @@ var TopStory = {
|
|
|
801
797
|
showTitle: true,
|
|
802
798
|
showStandfirst: true,
|
|
803
799
|
showPremiumLabel: true,
|
|
804
|
-
|
|
800
|
+
showExclusiveLabel: false,
|
|
805
801
|
showStatus: true,
|
|
806
802
|
showRelatedLinks: true
|
|
807
803
|
};
|
|
@@ -812,7 +808,7 @@ var TopStoryLandscape = {
|
|
|
812
808
|
showTitle: true,
|
|
813
809
|
showStandfirst: true,
|
|
814
810
|
showPremiumLabel: true,
|
|
815
|
-
|
|
811
|
+
showExclusiveLabel: false,
|
|
816
812
|
showStatus: true,
|
|
817
813
|
showImage: true,
|
|
818
814
|
imageSize: 'XL',
|
package/dist/Teaser.esm.js
CHANGED
|
@@ -493,11 +493,11 @@ function PremiumLabel() {
|
|
|
493
493
|
);
|
|
494
494
|
}
|
|
495
495
|
|
|
496
|
-
function
|
|
496
|
+
function ExclusiveLabel() {
|
|
497
497
|
return h("div", {
|
|
498
|
-
className: "o-teaser__labels o-teaser__labels--
|
|
498
|
+
className: "o-teaser__labels o-teaser__labels--exclusive"
|
|
499
499
|
}, h("span", {
|
|
500
|
-
className: "o-labels o-labels--content-
|
|
500
|
+
className: "o-labels o-labels--content-exclusive"
|
|
501
501
|
}, "Exclusive"), h("span", {
|
|
502
502
|
className: "o3-visually-hidden"
|
|
503
503
|
}, "\xA0content"));
|
|
@@ -508,12 +508,8 @@ var Status = props => {
|
|
|
508
508
|
if (props.showStatus && props.status) {
|
|
509
509
|
return h(LiveBlogStatus, props);
|
|
510
510
|
}
|
|
511
|
-
if (props.
|
|
512
|
-
|
|
513
|
-
// If we later show it on other pages, this cutoff date will need review.
|
|
514
|
-
// The `isScoop` property already exists, but Editorial will use it differently after 2025-10-01.
|
|
515
|
-
new Date(props.firstPublishedDate) >= new Date('2025-10-01T00:00:00.000Z')) {
|
|
516
|
-
return h(ScoopLabel, props);
|
|
511
|
+
if (props.showExclusiveLabel && props !== null && props !== void 0 && (_props$indicators = props.indicators) !== null && _props$indicators !== void 0 && _props$indicators.isExclusive) {
|
|
512
|
+
return h(ExclusiveLabel, props);
|
|
517
513
|
}
|
|
518
514
|
if (props.showPremiumLabel && (props === null || props === void 0 || (_props$indicators2 = props.indicators) === null || _props$indicators2 === void 0 ? void 0 : _props$indicators2.accessLevel) === 'premium') {
|
|
519
515
|
return h(PremiumLabel, props);
|
|
@@ -630,7 +626,7 @@ const Small = {
|
|
|
630
626
|
showMeta: true,
|
|
631
627
|
showTitle: true,
|
|
632
628
|
showPremiumLabel: true,
|
|
633
|
-
|
|
629
|
+
showExclusiveLabel: false,
|
|
634
630
|
showStatus: true
|
|
635
631
|
};
|
|
636
632
|
const SmallHeavy = {
|
|
@@ -640,7 +636,7 @@ const SmallHeavy = {
|
|
|
640
636
|
showTitle: true,
|
|
641
637
|
showStandfirst: true,
|
|
642
638
|
showPremiumLabel: true,
|
|
643
|
-
|
|
639
|
+
showExclusiveLabel: false,
|
|
644
640
|
showStatus: true,
|
|
645
641
|
showImage: true,
|
|
646
642
|
imageSize: 'Small'
|
|
@@ -652,7 +648,7 @@ const Large = {
|
|
|
652
648
|
showTitle: true,
|
|
653
649
|
showStandfirst: true,
|
|
654
650
|
showPremiumLabel: true,
|
|
655
|
-
|
|
651
|
+
showExclusiveLabel: false,
|
|
656
652
|
showStatus: true,
|
|
657
653
|
showImage: true,
|
|
658
654
|
imageSize: 'Medium'
|
|
@@ -663,7 +659,7 @@ const Hero = {
|
|
|
663
659
|
showMeta: true,
|
|
664
660
|
showTitle: true,
|
|
665
661
|
showPremiumLabel: true,
|
|
666
|
-
|
|
662
|
+
showExclusiveLabel: false,
|
|
667
663
|
showStatus: true,
|
|
668
664
|
showImage: true,
|
|
669
665
|
imageSize: 'Medium'
|
|
@@ -675,7 +671,7 @@ const HeroNarrow = {
|
|
|
675
671
|
showTitle: true,
|
|
676
672
|
showStandfirst: true,
|
|
677
673
|
showPremiumLabel: true,
|
|
678
|
-
|
|
674
|
+
showExclusiveLabel: false,
|
|
679
675
|
showStatus: true
|
|
680
676
|
};
|
|
681
677
|
const HeroVideo = {
|
|
@@ -692,7 +688,7 @@ const HeroOverlay = {
|
|
|
692
688
|
showMeta: true,
|
|
693
689
|
showTitle: true,
|
|
694
690
|
showPremiumLabel: true,
|
|
695
|
-
|
|
691
|
+
showExclusiveLabel: false,
|
|
696
692
|
showStatus: true,
|
|
697
693
|
showImage: true,
|
|
698
694
|
imageSize: 'XL',
|
|
@@ -705,7 +701,7 @@ const TopStory = {
|
|
|
705
701
|
showTitle: true,
|
|
706
702
|
showStandfirst: true,
|
|
707
703
|
showPremiumLabel: true,
|
|
708
|
-
|
|
704
|
+
showExclusiveLabel: false,
|
|
709
705
|
showStatus: true,
|
|
710
706
|
showRelatedLinks: true
|
|
711
707
|
};
|
|
@@ -716,7 +712,7 @@ const TopStoryLandscape = {
|
|
|
716
712
|
showTitle: true,
|
|
717
713
|
showStandfirst: true,
|
|
718
714
|
showPremiumLabel: true,
|
|
719
|
-
|
|
715
|
+
showExclusiveLabel: false,
|
|
720
716
|
showStatus: true,
|
|
721
717
|
showImage: true,
|
|
722
718
|
imageSize: 'XL',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@financial-times/x-teaser",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "19.0.0",
|
|
4
4
|
"description": "This module provides templates for use with o-teaser. Teasers are used to present content.",
|
|
5
5
|
"source": "src/Teaser.jsx",
|
|
6
6
|
"main": "dist/Teaser.cjs.js",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"author": "",
|
|
19
19
|
"license": "ISC",
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@financial-times/x-engine": "^
|
|
21
|
+
"@financial-times/x-engine": "^19.0.0",
|
|
22
22
|
"dateformat": "^3.0.3"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
package/readme.md
CHANGED
|
@@ -114,7 +114,7 @@ As covered in the [features](#features) documentation the teaser properties, or
|
|
|
114
114
|
| `showTitle` | Boolean |
|
|
115
115
|
| `showStandfirst` | Boolean |
|
|
116
116
|
| `showPremiumLabel` | Boolean |
|
|
117
|
-
| `
|
|
117
|
+
| `showExclusiveLabel` | Boolean |
|
|
118
118
|
| `showStatus` | Boolean |
|
|
119
119
|
| `showImage` | Boolean |
|
|
120
120
|
| `showHeadshot` | Boolean | Takes precedence over image |
|
|
@@ -255,7 +255,7 @@ As covered in the [features](#features) documentation the teaser properties, or
|
|
|
255
255
|
| `isColumn` | Boolean |
|
|
256
256
|
| `isPodcast` | Boolean |
|
|
257
257
|
| `isEditorsChoice` | Boolean |
|
|
258
|
-
| `isExclusive` | Boolean |
|
|
258
|
+
| `isExclusive` | Boolean | Controls whether the Exclusive badge is displayed |
|
|
259
259
|
| `isScoop` | Boolean |
|
|
260
260
|
|
|
261
261
|
#### Special Styling Props
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { h } from '@financial-times/x-engine'
|
|
2
|
+
|
|
3
|
+
export default function ExclusiveLabel() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="o-teaser__labels o-teaser__labels--exclusive">
|
|
6
|
+
<span className="o-labels o-labels--content-exclusive">Exclusive</span>
|
|
7
|
+
<span className="o3-visually-hidden"> content</span>
|
|
8
|
+
</div>
|
|
9
|
+
)
|
|
10
|
+
}
|
package/src/Status.jsx
CHANGED
|
@@ -4,22 +4,15 @@ import RelativeTime from './RelativeTime'
|
|
|
4
4
|
import LiveBlogStatus from './LiveBlogStatus'
|
|
5
5
|
import AlwaysShowTimestamp from './AlwaysShowTimestamp'
|
|
6
6
|
import PremiumLabel from './PremiumLabel'
|
|
7
|
-
import
|
|
7
|
+
import ExclusiveLabel from './ExclusiveLabel'
|
|
8
8
|
|
|
9
9
|
export default (props) => {
|
|
10
10
|
if (props.showStatus && props.status) {
|
|
11
11
|
return <LiveBlogStatus {...props} />
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
if (
|
|
15
|
-
props
|
|
16
|
-
props?.indicators?.isScoop &&
|
|
17
|
-
// We plan to show the Scoop label only on homepages.
|
|
18
|
-
// If we later show it on other pages, this cutoff date will need review.
|
|
19
|
-
// The `isScoop` property already exists, but Editorial will use it differently after 2025-10-01.
|
|
20
|
-
new Date(props.firstPublishedDate) >= new Date('2025-10-01T00:00:00.000Z')
|
|
21
|
-
) {
|
|
22
|
-
return <ScoopLabel {...props} />
|
|
14
|
+
if (props.showExclusiveLabel && props?.indicators?.isExclusive) {
|
|
15
|
+
return <ExclusiveLabel {...props} />
|
|
23
16
|
}
|
|
24
17
|
|
|
25
18
|
if (props.showPremiumLabel && props?.indicators?.accessLevel === 'premium') {
|
package/src/concerns/presets.js
CHANGED
|
@@ -6,7 +6,7 @@ const Small = {
|
|
|
6
6
|
showMeta: true,
|
|
7
7
|
showTitle: true,
|
|
8
8
|
showPremiumLabel: true,
|
|
9
|
-
|
|
9
|
+
showExclusiveLabel: false,
|
|
10
10
|
showStatus: true
|
|
11
11
|
}
|
|
12
12
|
|
|
@@ -17,7 +17,7 @@ const SmallHeavy = {
|
|
|
17
17
|
showTitle: true,
|
|
18
18
|
showStandfirst: true,
|
|
19
19
|
showPremiumLabel: true,
|
|
20
|
-
|
|
20
|
+
showExclusiveLabel: false,
|
|
21
21
|
showStatus: true,
|
|
22
22
|
showImage: true,
|
|
23
23
|
imageSize: 'Small'
|
|
@@ -30,7 +30,7 @@ const Large = {
|
|
|
30
30
|
showTitle: true,
|
|
31
31
|
showStandfirst: true,
|
|
32
32
|
showPremiumLabel: true,
|
|
33
|
-
|
|
33
|
+
showExclusiveLabel: false,
|
|
34
34
|
showStatus: true,
|
|
35
35
|
showImage: true,
|
|
36
36
|
imageSize: 'Medium'
|
|
@@ -42,7 +42,7 @@ const Hero = {
|
|
|
42
42
|
showMeta: true,
|
|
43
43
|
showTitle: true,
|
|
44
44
|
showPremiumLabel: true,
|
|
45
|
-
|
|
45
|
+
showExclusiveLabel: false,
|
|
46
46
|
showStatus: true,
|
|
47
47
|
showImage: true,
|
|
48
48
|
imageSize: 'Medium'
|
|
@@ -55,7 +55,7 @@ const HeroNarrow = {
|
|
|
55
55
|
showTitle: true,
|
|
56
56
|
showStandfirst: true,
|
|
57
57
|
showPremiumLabel: true,
|
|
58
|
-
|
|
58
|
+
showExclusiveLabel: false,
|
|
59
59
|
showStatus: true
|
|
60
60
|
}
|
|
61
61
|
|
|
@@ -74,7 +74,7 @@ const HeroOverlay = {
|
|
|
74
74
|
showMeta: true,
|
|
75
75
|
showTitle: true,
|
|
76
76
|
showPremiumLabel: true,
|
|
77
|
-
|
|
77
|
+
showExclusiveLabel: false,
|
|
78
78
|
showStatus: true,
|
|
79
79
|
showImage: true,
|
|
80
80
|
imageSize: 'XL',
|
|
@@ -88,7 +88,7 @@ const TopStory = {
|
|
|
88
88
|
showTitle: true,
|
|
89
89
|
showStandfirst: true,
|
|
90
90
|
showPremiumLabel: true,
|
|
91
|
-
|
|
91
|
+
showExclusiveLabel: false,
|
|
92
92
|
showStatus: true,
|
|
93
93
|
showRelatedLinks: true
|
|
94
94
|
}
|
|
@@ -100,7 +100,7 @@ const TopStoryLandscape = {
|
|
|
100
100
|
showTitle: true,
|
|
101
101
|
showStandfirst: true,
|
|
102
102
|
showPremiumLabel: true,
|
|
103
|
-
|
|
103
|
+
showExclusiveLabel: false,
|
|
104
104
|
showStatus: true,
|
|
105
105
|
showImage: true,
|
|
106
106
|
imageSize: 'XL',
|
package/storybook/index.jsx
CHANGED
package/src/ScoopLabel.jsx
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { h } from '@financial-times/x-engine'
|
|
2
|
-
|
|
3
|
-
export default function ScoopLabel() {
|
|
4
|
-
return (
|
|
5
|
-
<div className="o-teaser__labels o-teaser__labels--scoop">
|
|
6
|
-
<span className="o-labels o-labels--content-scoop">Exclusive</span>
|
|
7
|
-
<span className="o3-visually-hidden"> content</span>
|
|
8
|
-
</div>
|
|
9
|
-
)
|
|
10
|
-
}
|