@financial-times/x-teaser 20.0.0-beta.2 → 20.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/__tests__/CustomSlotTop.test.jsx +38 -0
- package/__tests__/__snapshots__/CustomSlotTop.test.jsx.snap +25 -0
- package/__tests__/__snapshots__/snapshots.test.js.snap +18 -0
- package/__tests__/same-label.test.js +24 -0
- package/dist/Teaser.cjs.js +28 -3
- package/dist/Teaser.es5.js +29 -3
- package/dist/Teaser.esm.js +28 -3
- package/package.json +2 -2
- package/src/CustomSlotTop.jsx +17 -0
- package/src/Teaser.jsx +2 -0
- package/src/Title.jsx +2 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const { h } = require('@financial-times/x-engine')
|
|
2
|
+
const { mount } = require('@financial-times/x-test-utils/enzyme')
|
|
3
|
+
const renderer = require('react-test-renderer')
|
|
4
|
+
const { Teaser } = require('../')
|
|
5
|
+
const article = require('../__fixtures__/article.json')
|
|
6
|
+
|
|
7
|
+
describe('x-teaser / CustomSlotTop', () => {
|
|
8
|
+
let props
|
|
9
|
+
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
props = {
|
|
12
|
+
...article,
|
|
13
|
+
showTitle: true
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
it('should not render a custom slot top as default', () => {
|
|
18
|
+
const tree = renderer.create(h(Teaser, props)).toJSON()
|
|
19
|
+
expect(tree).toMatchSnapshot()
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('render a custom slot top with a string', () => {
|
|
23
|
+
const customSlotTopHTML = '<p>Some HTML</p>'
|
|
24
|
+
props.showCustomSlotTop = true
|
|
25
|
+
props.customSlotTop = customSlotTopHTML
|
|
26
|
+
const subject = mount(<Teaser {...props} />)
|
|
27
|
+
expect(subject.find('.x-teaser-custom-slot-top').html()).toBe(
|
|
28
|
+
`<div class="x-teaser-custom-slot-top">${customSlotTopHTML}</div>`
|
|
29
|
+
)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('render a custom slot top with a React element', () => {
|
|
33
|
+
props.showCustomSlotTop = true
|
|
34
|
+
props.customSlotTop = <div className="custom-slot-top--with-react-element">Custom slot top content</div>
|
|
35
|
+
const subject = mount(<Teaser {...props} />)
|
|
36
|
+
expect(subject.find('.custom-slot-top--with-react-element')).toBeTruthy()
|
|
37
|
+
})
|
|
38
|
+
})
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`x-teaser / CustomSlotTop should not render a custom slot top as default 1`] = `
|
|
4
|
+
<div
|
|
5
|
+
className="o-teaser o-teaser--article o-teaser--highlight js-teaser"
|
|
6
|
+
data-id=""
|
|
7
|
+
>
|
|
8
|
+
<div
|
|
9
|
+
className="o-teaser__content"
|
|
10
|
+
>
|
|
11
|
+
<div
|
|
12
|
+
className="o-teaser__heading"
|
|
13
|
+
>
|
|
14
|
+
<a
|
|
15
|
+
className="js-teaser-heading-link"
|
|
16
|
+
data-trackable="heading-link"
|
|
17
|
+
data-trackable-context-story-link="heading-link"
|
|
18
|
+
href="#"
|
|
19
|
+
>
|
|
20
|
+
Inside charity fundraiser where hostesses are put on show
|
|
21
|
+
</a>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
`;
|
|
@@ -256,6 +256,7 @@ exports[`x-teaser / snapshots renders a Hero teaser with opinion data 1`] = `
|
|
|
256
256
|
className="o-teaser__heading"
|
|
257
257
|
>
|
|
258
258
|
<a
|
|
259
|
+
aria-label="Opinion content. Anti-Semitism and the threat of identity politics"
|
|
259
260
|
className="js-teaser-heading-link"
|
|
260
261
|
data-trackable="heading-link"
|
|
261
262
|
data-trackable-context-story-link="heading-link"
|
|
@@ -346,6 +347,7 @@ exports[`x-teaser / snapshots renders a Hero teaser with packageItem data 1`] =
|
|
|
346
347
|
className="o-teaser__heading"
|
|
347
348
|
>
|
|
348
349
|
<a
|
|
350
|
+
aria-label="Opinion content. Why so little has changed since the crash"
|
|
349
351
|
className="js-teaser-heading-link"
|
|
350
352
|
data-trackable="heading-link"
|
|
351
353
|
data-trackable-context-story-link="heading-link"
|
|
@@ -886,6 +888,7 @@ exports[`x-teaser / snapshots renders a HeroNarrow teaser with opinion data 1`]
|
|
|
886
888
|
className="o-teaser__heading"
|
|
887
889
|
>
|
|
888
890
|
<a
|
|
891
|
+
aria-label="Opinion content. Anti-Semitism and the threat of identity politics"
|
|
889
892
|
className="js-teaser-heading-link"
|
|
890
893
|
data-trackable="heading-link"
|
|
891
894
|
data-trackable-context-story-link="heading-link"
|
|
@@ -963,6 +966,7 @@ exports[`x-teaser / snapshots renders a HeroNarrow teaser with packageItem data
|
|
|
963
966
|
className="o-teaser__heading"
|
|
964
967
|
>
|
|
965
968
|
<a
|
|
969
|
+
aria-label="Opinion content. Why so little has changed since the crash"
|
|
966
970
|
className="js-teaser-heading-link"
|
|
967
971
|
data-trackable="heading-link"
|
|
968
972
|
data-trackable-context-story-link="heading-link"
|
|
@@ -1464,6 +1468,7 @@ exports[`x-teaser / snapshots renders a HeroOverlay teaser with opinion data 1`]
|
|
|
1464
1468
|
className="o-teaser__heading"
|
|
1465
1469
|
>
|
|
1466
1470
|
<a
|
|
1471
|
+
aria-label="Opinion content. Anti-Semitism and the threat of identity politics"
|
|
1467
1472
|
className="js-teaser-heading-link"
|
|
1468
1473
|
data-trackable="heading-link"
|
|
1469
1474
|
data-trackable-context-story-link="heading-link"
|
|
@@ -1554,6 +1559,7 @@ exports[`x-teaser / snapshots renders a HeroOverlay teaser with packageItem data
|
|
|
1554
1559
|
className="o-teaser__heading"
|
|
1555
1560
|
>
|
|
1556
1561
|
<a
|
|
1562
|
+
aria-label="Opinion content. Why so little has changed since the crash"
|
|
1557
1563
|
className="js-teaser-heading-link"
|
|
1558
1564
|
data-trackable="heading-link"
|
|
1559
1565
|
data-trackable-context-story-link="heading-link"
|
|
@@ -2042,6 +2048,7 @@ exports[`x-teaser / snapshots renders a HeroVideo teaser with opinion data 1`] =
|
|
|
2042
2048
|
className="o-teaser__heading"
|
|
2043
2049
|
>
|
|
2044
2050
|
<a
|
|
2051
|
+
aria-label="Opinion content. Anti-Semitism and the threat of identity politics"
|
|
2045
2052
|
className="js-teaser-heading-link"
|
|
2046
2053
|
data-trackable="heading-link"
|
|
2047
2054
|
data-trackable-context-story-link="heading-link"
|
|
@@ -2106,6 +2113,7 @@ exports[`x-teaser / snapshots renders a HeroVideo teaser with packageItem data 1
|
|
|
2106
2113
|
className="o-teaser__heading"
|
|
2107
2114
|
>
|
|
2108
2115
|
<a
|
|
2116
|
+
aria-label="Opinion content. Why so little has changed since the crash"
|
|
2109
2117
|
className="js-teaser-heading-link"
|
|
2110
2118
|
data-trackable="heading-link"
|
|
2111
2119
|
data-trackable-context-story-link="heading-link"
|
|
@@ -2651,6 +2659,7 @@ exports[`x-teaser / snapshots renders a Large teaser with opinion data 1`] = `
|
|
|
2651
2659
|
className="o-teaser__heading"
|
|
2652
2660
|
>
|
|
2653
2661
|
<a
|
|
2662
|
+
aria-label="Opinion content. Anti-Semitism and the threat of identity politics"
|
|
2654
2663
|
className="js-teaser-heading-link"
|
|
2655
2664
|
data-trackable="heading-link"
|
|
2656
2665
|
data-trackable-context-story-link="heading-link"
|
|
@@ -2754,6 +2763,7 @@ exports[`x-teaser / snapshots renders a Large teaser with packageItem data 1`] =
|
|
|
2754
2763
|
className="o-teaser__heading"
|
|
2755
2764
|
>
|
|
2756
2765
|
<a
|
|
2766
|
+
aria-label="Opinion content. Why so little has changed since the crash"
|
|
2757
2767
|
className="js-teaser-heading-link"
|
|
2758
2768
|
data-trackable="heading-link"
|
|
2759
2769
|
data-trackable-context-story-link="heading-link"
|
|
@@ -3307,6 +3317,7 @@ exports[`x-teaser / snapshots renders a Small teaser with opinion data 1`] = `
|
|
|
3307
3317
|
className="o-teaser__heading"
|
|
3308
3318
|
>
|
|
3309
3319
|
<a
|
|
3320
|
+
aria-label="Opinion content. Anti-Semitism and the threat of identity politics"
|
|
3310
3321
|
className="js-teaser-heading-link"
|
|
3311
3322
|
data-trackable="heading-link"
|
|
3312
3323
|
data-trackable-context-story-link="heading-link"
|
|
@@ -3371,6 +3382,7 @@ exports[`x-teaser / snapshots renders a Small teaser with packageItem data 1`] =
|
|
|
3371
3382
|
className="o-teaser__heading"
|
|
3372
3383
|
>
|
|
3373
3384
|
<a
|
|
3385
|
+
aria-label="Opinion content. Why so little has changed since the crash"
|
|
3374
3386
|
className="js-teaser-heading-link"
|
|
3375
3387
|
data-trackable="heading-link"
|
|
3376
3388
|
data-trackable-context-story-link="heading-link"
|
|
@@ -3859,6 +3871,7 @@ exports[`x-teaser / snapshots renders a SmallHeavy teaser with opinion data 1`]
|
|
|
3859
3871
|
className="o-teaser__heading"
|
|
3860
3872
|
>
|
|
3861
3873
|
<a
|
|
3874
|
+
aria-label="Opinion content. Anti-Semitism and the threat of identity politics"
|
|
3862
3875
|
className="js-teaser-heading-link"
|
|
3863
3876
|
data-trackable="heading-link"
|
|
3864
3877
|
data-trackable-context-story-link="heading-link"
|
|
@@ -3962,6 +3975,7 @@ exports[`x-teaser / snapshots renders a SmallHeavy teaser with packageItem data
|
|
|
3962
3975
|
className="o-teaser__heading"
|
|
3963
3976
|
>
|
|
3964
3977
|
<a
|
|
3978
|
+
aria-label="Opinion content. Why so little has changed since the crash"
|
|
3965
3979
|
className="js-teaser-heading-link"
|
|
3966
3980
|
data-trackable="heading-link"
|
|
3967
3981
|
data-trackable-context-story-link="heading-link"
|
|
@@ -4567,6 +4581,7 @@ exports[`x-teaser / snapshots renders a TopStory teaser with opinion data 1`] =
|
|
|
4567
4581
|
className="o-teaser__heading"
|
|
4568
4582
|
>
|
|
4569
4583
|
<a
|
|
4584
|
+
aria-label="Opinion content. Anti-Semitism and the threat of identity politics"
|
|
4570
4585
|
className="js-teaser-heading-link"
|
|
4571
4586
|
data-trackable="heading-link"
|
|
4572
4587
|
data-trackable-context-story-link="heading-link"
|
|
@@ -4644,6 +4659,7 @@ exports[`x-teaser / snapshots renders a TopStory teaser with packageItem data 1`
|
|
|
4644
4659
|
className="o-teaser__heading"
|
|
4645
4660
|
>
|
|
4646
4661
|
<a
|
|
4662
|
+
aria-label="Opinion content. Why so little has changed since the crash"
|
|
4647
4663
|
className="js-teaser-heading-link"
|
|
4648
4664
|
data-trackable="heading-link"
|
|
4649
4665
|
data-trackable-context-story-link="heading-link"
|
|
@@ -5234,6 +5250,7 @@ exports[`x-teaser / snapshots renders a TopStoryLandscape teaser with opinion da
|
|
|
5234
5250
|
className="o-teaser__heading"
|
|
5235
5251
|
>
|
|
5236
5252
|
<a
|
|
5253
|
+
aria-label="Opinion content. Anti-Semitism and the threat of identity politics"
|
|
5237
5254
|
className="js-teaser-heading-link"
|
|
5238
5255
|
data-trackable="heading-link"
|
|
5239
5256
|
data-trackable-context-story-link="heading-link"
|
|
@@ -5337,6 +5354,7 @@ exports[`x-teaser / snapshots renders a TopStoryLandscape teaser with packageIte
|
|
|
5337
5354
|
className="o-teaser__heading"
|
|
5338
5355
|
>
|
|
5339
5356
|
<a
|
|
5357
|
+
aria-label="Opinion content. Why so little has changed since the crash"
|
|
5340
5358
|
className="js-teaser-heading-link"
|
|
5341
5359
|
data-trackable="heading-link"
|
|
5342
5360
|
data-trackable-context-story-link="heading-link"
|
|
@@ -16,4 +16,28 @@ describe('same-label', () => {
|
|
|
16
16
|
expect(sameLabel(context, label)).toBe(false)
|
|
17
17
|
})
|
|
18
18
|
})
|
|
19
|
+
|
|
20
|
+
describe('when label is undefined', () => {
|
|
21
|
+
it('returns false', () => {
|
|
22
|
+
const context = { parentLabel: 'Opinion' }
|
|
23
|
+
const label = undefined
|
|
24
|
+
expect(sameLabel(context, label)).toBe(false)
|
|
25
|
+
})
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
describe('when context.parentLabel is undefined', () => {
|
|
29
|
+
it('returns false', () => {
|
|
30
|
+
const context = { parentLabel: undefined }
|
|
31
|
+
const label = 'News'
|
|
32
|
+
expect(sameLabel(context, label)).toBe(false)
|
|
33
|
+
})
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
describe('when both label and context.parentLabel are undefined', () => {
|
|
37
|
+
it('returns false', () => {
|
|
38
|
+
const context = { parentLabel: undefined }
|
|
39
|
+
const label = undefined
|
|
40
|
+
expect(sameLabel(context, label)).toBe(false)
|
|
41
|
+
})
|
|
42
|
+
})
|
|
19
43
|
})
|
package/dist/Teaser.cjs.js
CHANGED
|
@@ -98,12 +98,34 @@ var Content = ({
|
|
|
98
98
|
className: "o-teaser__content"
|
|
99
99
|
}, children);
|
|
100
100
|
|
|
101
|
+
/**
|
|
102
|
+
* Render
|
|
103
|
+
* @param {String|ReactElement} slot
|
|
104
|
+
* @returns {ReactElement}
|
|
105
|
+
*/
|
|
106
|
+
const render = slot => {
|
|
107
|
+
// Allow parent components to pass raw HTML strings
|
|
108
|
+
if (typeof slot === 'string') {
|
|
109
|
+
return xEngine.h("div", {
|
|
110
|
+
className: "x-teaser-custom-slot-top",
|
|
111
|
+
dangerouslySetInnerHTML: {
|
|
112
|
+
__html: slot
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
} else {
|
|
116
|
+
return slot;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
var CustomSlotTop = ({
|
|
120
|
+
customSlotTop
|
|
121
|
+
}) => customSlotTop ? render(customSlotTop) : null;
|
|
122
|
+
|
|
101
123
|
/**
|
|
102
124
|
* Render
|
|
103
125
|
* @param {String|ReactElement} action
|
|
104
126
|
* @returns {ReactElement}
|
|
105
127
|
*/
|
|
106
|
-
const render = action => {
|
|
128
|
+
const render$1 = action => {
|
|
107
129
|
// Allow parent components to pass raw HTML strings
|
|
108
130
|
if (typeof action === 'string') {
|
|
109
131
|
return xEngine.h("span", {
|
|
@@ -119,7 +141,7 @@ var CustomSlot = ({
|
|
|
119
141
|
customSlot
|
|
120
142
|
}) => customSlot ? xEngine.h("div", {
|
|
121
143
|
className: "o-teaser__action"
|
|
122
|
-
}, render(customSlot)) : null;
|
|
144
|
+
}, render$1(customSlot)) : null;
|
|
123
145
|
|
|
124
146
|
const ImageSizes = {
|
|
125
147
|
Headshot: 75,
|
|
@@ -647,6 +669,7 @@ var Title = ({
|
|
|
647
669
|
url,
|
|
648
670
|
...props
|
|
649
671
|
}) => {
|
|
672
|
+
var _props$indicators;
|
|
650
673
|
const displayTitle = headlineTesting && altTitle ? altTitle : title;
|
|
651
674
|
const displayUrl = relativeUrl || url;
|
|
652
675
|
let ariaLabel;
|
|
@@ -654,6 +677,8 @@ var Title = ({
|
|
|
654
677
|
ariaLabel = `Watch video ${displayTitle}`;
|
|
655
678
|
} else if (props.type === 'audio') {
|
|
656
679
|
ariaLabel = `Listen to podcast ${displayTitle}`;
|
|
680
|
+
} else if (((_props$indicators = props.indicators) === null || _props$indicators === void 0 ? void 0 : _props$indicators.isOpinion) === true) {
|
|
681
|
+
ariaLabel = `Opinion content. ${displayTitle}`;
|
|
657
682
|
}
|
|
658
683
|
return xEngine.h("div", {
|
|
659
684
|
className: "o-teaser__heading"
|
|
@@ -850,7 +875,7 @@ var presets = {
|
|
|
850
875
|
TopStoryLandscape
|
|
851
876
|
};
|
|
852
877
|
|
|
853
|
-
const Teaser = props => xEngine.h(Container, props, xEngine.h(Content, null, props.showMeta ? xEngine.h(Meta, props) : null, media(props) === 'video' ? xEngine.h(Video, props) : null, props.showTitle ? xEngine.h(Title, props) : null, props.showStandfirst ? xEngine.h(Standfirst, props) : null, props.showByline ? xEngine.h(Byline, props) : null, xEngine.h(Status, props), props.showCustomSlot ? xEngine.h(CustomSlot, props) : null,
|
|
878
|
+
const Teaser = props => xEngine.h(Container, props, xEngine.h(Content, null, props.showCustomSlotTop ? xEngine.h(CustomSlotTop, props) : null, props.showMeta ? xEngine.h(Meta, props) : null, media(props) === 'video' ? xEngine.h(Video, props) : null, props.showTitle ? xEngine.h(Title, props) : null, props.showStandfirst ? xEngine.h(Standfirst, props) : null, props.showByline ? xEngine.h(Byline, props) : null, xEngine.h(Status, props), props.showCustomSlot ? xEngine.h(CustomSlot, props) : null,
|
|
854
879
|
/* Headshot is a legacy element.
|
|
855
880
|
The Byline component already includes a headshot.
|
|
856
881
|
Only render the Headshot when the media rule `headshot` is true,
|
package/dist/Teaser.es5.js
CHANGED
|
@@ -106,12 +106,35 @@ var Content = (function (_ref) {
|
|
|
106
106
|
}, children);
|
|
107
107
|
});
|
|
108
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Render
|
|
111
|
+
* @param {String|ReactElement} slot
|
|
112
|
+
* @returns {ReactElement}
|
|
113
|
+
*/
|
|
114
|
+
var render = function render(slot) {
|
|
115
|
+
// Allow parent components to pass raw HTML strings
|
|
116
|
+
if (typeof slot === 'string') {
|
|
117
|
+
return xEngine.h("div", {
|
|
118
|
+
className: "x-teaser-custom-slot-top",
|
|
119
|
+
dangerouslySetInnerHTML: {
|
|
120
|
+
__html: slot
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
} else {
|
|
124
|
+
return slot;
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
var CustomSlotTop = (function (_ref) {
|
|
128
|
+
var customSlotTop = _ref.customSlotTop;
|
|
129
|
+
return customSlotTop ? render(customSlotTop) : null;
|
|
130
|
+
});
|
|
131
|
+
|
|
109
132
|
/**
|
|
110
133
|
* Render
|
|
111
134
|
* @param {String|ReactElement} action
|
|
112
135
|
* @returns {ReactElement}
|
|
113
136
|
*/
|
|
114
|
-
var render = function render(action) {
|
|
137
|
+
var render$1 = function render(action) {
|
|
115
138
|
// Allow parent components to pass raw HTML strings
|
|
116
139
|
if (typeof action === 'string') {
|
|
117
140
|
return xEngine.h("span", {
|
|
@@ -127,7 +150,7 @@ var CustomSlot = (function (_ref) {
|
|
|
127
150
|
var customSlot = _ref.customSlot;
|
|
128
151
|
return customSlot ? xEngine.h("div", {
|
|
129
152
|
className: "o-teaser__action"
|
|
130
|
-
}, render(customSlot)) : null;
|
|
153
|
+
}, render$1(customSlot)) : null;
|
|
131
154
|
});
|
|
132
155
|
|
|
133
156
|
function _iterableToArrayLimit(r, l) {
|
|
@@ -792,6 +815,7 @@ var Standfirst = (function (_ref) {
|
|
|
792
815
|
|
|
793
816
|
var _excluded$3 = ["title", "altTitle", "showTitlePrefix", "titlePrefix", "headlineTesting", "relativeUrl", "url"];
|
|
794
817
|
var Title = (function (_ref) {
|
|
818
|
+
var _props$indicators;
|
|
795
819
|
var title = _ref.title,
|
|
796
820
|
altTitle = _ref.altTitle,
|
|
797
821
|
showTitlePrefix = _ref.showTitlePrefix,
|
|
@@ -807,6 +831,8 @@ var Title = (function (_ref) {
|
|
|
807
831
|
ariaLabel = "Watch video ".concat(displayTitle);
|
|
808
832
|
} else if (props.type === 'audio') {
|
|
809
833
|
ariaLabel = "Listen to podcast ".concat(displayTitle);
|
|
834
|
+
} else if (((_props$indicators = props.indicators) === null || _props$indicators === void 0 ? void 0 : _props$indicators.isOpinion) === true) {
|
|
835
|
+
ariaLabel = "Opinion content. ".concat(displayTitle);
|
|
810
836
|
}
|
|
811
837
|
return xEngine.h("div", {
|
|
812
838
|
className: "o-teaser__heading"
|
|
@@ -1009,7 +1035,7 @@ var presets = {
|
|
|
1009
1035
|
};
|
|
1010
1036
|
|
|
1011
1037
|
var Teaser = function Teaser(props) {
|
|
1012
|
-
return xEngine.h(Container, props, xEngine.h(Content, null, props.showMeta ? xEngine.h(Meta, props) : null, media(props) === 'video' ? xEngine.h(Video, props) : null, props.showTitle ? xEngine.h(Title, props) : null, props.showStandfirst ? xEngine.h(Standfirst, props) : null, props.showByline ? xEngine.h(Byline, props) : null, xEngine.h(Status, props), props.showCustomSlot ? xEngine.h(CustomSlot, props) : null,
|
|
1038
|
+
return xEngine.h(Container, props, xEngine.h(Content, null, props.showCustomSlotTop ? xEngine.h(CustomSlotTop, props) : null, props.showMeta ? xEngine.h(Meta, props) : null, media(props) === 'video' ? xEngine.h(Video, props) : null, props.showTitle ? xEngine.h(Title, props) : null, props.showStandfirst ? xEngine.h(Standfirst, props) : null, props.showByline ? xEngine.h(Byline, props) : null, xEngine.h(Status, props), props.showCustomSlot ? xEngine.h(CustomSlot, props) : null,
|
|
1013
1039
|
/* Headshot is a legacy element.
|
|
1014
1040
|
The Byline component already includes a headshot.
|
|
1015
1041
|
Only render the Headshot when the media rule `headshot` is true,
|
package/dist/Teaser.esm.js
CHANGED
|
@@ -92,12 +92,34 @@ var Content = ({
|
|
|
92
92
|
className: "o-teaser__content"
|
|
93
93
|
}, children);
|
|
94
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Render
|
|
97
|
+
* @param {String|ReactElement} slot
|
|
98
|
+
* @returns {ReactElement}
|
|
99
|
+
*/
|
|
100
|
+
const render = slot => {
|
|
101
|
+
// Allow parent components to pass raw HTML strings
|
|
102
|
+
if (typeof slot === 'string') {
|
|
103
|
+
return h("div", {
|
|
104
|
+
className: "x-teaser-custom-slot-top",
|
|
105
|
+
dangerouslySetInnerHTML: {
|
|
106
|
+
__html: slot
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
} else {
|
|
110
|
+
return slot;
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
var CustomSlotTop = ({
|
|
114
|
+
customSlotTop
|
|
115
|
+
}) => customSlotTop ? render(customSlotTop) : null;
|
|
116
|
+
|
|
95
117
|
/**
|
|
96
118
|
* Render
|
|
97
119
|
* @param {String|ReactElement} action
|
|
98
120
|
* @returns {ReactElement}
|
|
99
121
|
*/
|
|
100
|
-
const render = action => {
|
|
122
|
+
const render$1 = action => {
|
|
101
123
|
// Allow parent components to pass raw HTML strings
|
|
102
124
|
if (typeof action === 'string') {
|
|
103
125
|
return h("span", {
|
|
@@ -113,7 +135,7 @@ var CustomSlot = ({
|
|
|
113
135
|
customSlot
|
|
114
136
|
}) => customSlot ? h("div", {
|
|
115
137
|
className: "o-teaser__action"
|
|
116
|
-
}, render(customSlot)) : null;
|
|
138
|
+
}, render$1(customSlot)) : null;
|
|
117
139
|
|
|
118
140
|
const ImageSizes = {
|
|
119
141
|
Headshot: 75,
|
|
@@ -641,6 +663,7 @@ var Title = ({
|
|
|
641
663
|
url,
|
|
642
664
|
...props
|
|
643
665
|
}) => {
|
|
666
|
+
var _props$indicators;
|
|
644
667
|
const displayTitle = headlineTesting && altTitle ? altTitle : title;
|
|
645
668
|
const displayUrl = relativeUrl || url;
|
|
646
669
|
let ariaLabel;
|
|
@@ -648,6 +671,8 @@ var Title = ({
|
|
|
648
671
|
ariaLabel = `Watch video ${displayTitle}`;
|
|
649
672
|
} else if (props.type === 'audio') {
|
|
650
673
|
ariaLabel = `Listen to podcast ${displayTitle}`;
|
|
674
|
+
} else if (((_props$indicators = props.indicators) === null || _props$indicators === void 0 ? void 0 : _props$indicators.isOpinion) === true) {
|
|
675
|
+
ariaLabel = `Opinion content. ${displayTitle}`;
|
|
651
676
|
}
|
|
652
677
|
return h("div", {
|
|
653
678
|
className: "o-teaser__heading"
|
|
@@ -844,7 +869,7 @@ var presets = {
|
|
|
844
869
|
TopStoryLandscape
|
|
845
870
|
};
|
|
846
871
|
|
|
847
|
-
const Teaser = props => h(Container, props, h(Content, null, props.showMeta ? h(Meta, props) : null, media(props) === 'video' ? h(Video, props) : null, props.showTitle ? h(Title, props) : null, props.showStandfirst ? h(Standfirst, props) : null, props.showByline ? h(Byline, props) : null, h(Status, props), props.showCustomSlot ? h(CustomSlot, props) : null,
|
|
872
|
+
const Teaser = props => h(Container, props, h(Content, null, props.showCustomSlotTop ? h(CustomSlotTop, props) : null, props.showMeta ? h(Meta, props) : null, media(props) === 'video' ? h(Video, props) : null, props.showTitle ? h(Title, props) : null, props.showStandfirst ? h(Standfirst, props) : null, props.showByline ? h(Byline, props) : null, h(Status, props), props.showCustomSlot ? h(CustomSlot, props) : null,
|
|
848
873
|
/* Headshot is a legacy element.
|
|
849
874
|
The Byline component already includes a headshot.
|
|
850
875
|
Only render the Headshot when the media rule `headshot` is true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@financial-times/x-teaser",
|
|
3
|
-
"version": "20.0.0
|
|
3
|
+
"version": "20.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": "^20.0.0
|
|
21
|
+
"@financial-times/x-engine": "^20.0.0",
|
|
22
22
|
"dateformat": "^3.0.3"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { h } from '@financial-times/x-engine'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Render
|
|
5
|
+
* @param {String|ReactElement} slot
|
|
6
|
+
* @returns {ReactElement}
|
|
7
|
+
*/
|
|
8
|
+
const render = (slot) => {
|
|
9
|
+
// Allow parent components to pass raw HTML strings
|
|
10
|
+
if (typeof slot === 'string') {
|
|
11
|
+
return <div className="x-teaser-custom-slot-top" dangerouslySetInnerHTML={{ __html: slot }} />
|
|
12
|
+
} else {
|
|
13
|
+
return slot
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default ({ customSlotTop }) => (customSlotTop ? render(customSlotTop) : null)
|
package/src/Teaser.jsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { h } from '@financial-times/x-engine'
|
|
2
2
|
import Container from './Container'
|
|
3
3
|
import Content from './Content'
|
|
4
|
+
import CustomSlotTop from './CustomSlotTop'
|
|
4
5
|
import CustomSlot from './CustomSlot'
|
|
5
6
|
import Byline from './Byline'
|
|
6
7
|
import Headshot from './Headshot'
|
|
@@ -18,6 +19,7 @@ import presets from './concerns/presets'
|
|
|
18
19
|
const Teaser = (props) => (
|
|
19
20
|
<Container {...props}>
|
|
20
21
|
<Content>
|
|
22
|
+
{props.showCustomSlotTop ? <CustomSlotTop {...props} /> : null}
|
|
21
23
|
{props.showMeta ? <Meta {...props} /> : null}
|
|
22
24
|
{media(props) === 'video' ? <Video {...props} /> : null}
|
|
23
25
|
{props.showTitle ? <Title {...props} /> : null}
|
package/src/Title.jsx
CHANGED
|
@@ -20,6 +20,8 @@ export default ({
|
|
|
20
20
|
ariaLabel = `Watch video ${displayTitle}`
|
|
21
21
|
} else if (props.type === 'audio') {
|
|
22
22
|
ariaLabel = `Listen to podcast ${displayTitle}`
|
|
23
|
+
} else if (props.indicators?.isOpinion === true) {
|
|
24
|
+
ariaLabel = `Opinion content. ${displayTitle}`
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
return (
|