@financial-times/cp-content-pipeline-ui 9.9.0 → 9.11.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 +31 -0
- package/lib/components/Topper/{Columnist.d.ts → Columnists.d.ts} +3 -3
- package/lib/components/Topper/Columnists.js +22 -0
- package/lib/components/Topper/Columnists.js.map +1 -0
- package/lib/components/Topper/Tags.d.ts +1 -1
- package/lib/components/Topper/Tags.js +2 -2
- package/lib/components/Topper/Tags.js.map +1 -1
- package/lib/components/Topper/index.js +17 -8
- package/lib/components/Topper/index.js.map +1 -1
- package/lib/components/content-tree/Clip/components/ClipTag.d.ts +1 -0
- package/lib/components/content-tree/Clip/components/ClipTag.js +32 -3
- package/lib/components/content-tree/Clip/components/ClipTag.js.map +1 -1
- package/lib/components/content-tree/Clip/template/component.d.ts +1 -0
- 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/Workarounds.d.ts +3 -0
- package/package.json +4 -4
- package/src/components/Topper/Columnists.tsx +50 -0
- package/src/components/Topper/Tags.tsx +3 -3
- package/src/components/Topper/index.tsx +21 -10
- package/src/components/content-tree/Clip/components/ClipTag.tsx +58 -11
- package/src/components/content-tree/Clip/template/component.tsx +4 -0
- package/src/components/content-tree/Workarounds.ts +3 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/lib/components/Topper/Columnist.js +0 -18
- package/lib/components/Topper/Columnist.js.map +0 -1
- package/src/components/Topper/Columnist.tsx +0 -40
package/CHANGELOG.md
CHANGED
|
@@ -574,6 +574,37 @@
|
|
|
574
574
|
* @financial-times/cp-content-pipeline-client bumped from ^3.7.2 to ^3.7.3
|
|
575
575
|
* @financial-times/cp-content-pipeline-schema bumped from ^2.10.1 to ^2.10.2
|
|
576
576
|
|
|
577
|
+
## [9.11.0](https://github.com/Financial-Times/cp-content-pipeline/compare/cp-content-pipeline-ui-v9.10.0...cp-content-pipeline-ui-v9.11.0) (2025-11-11)
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
### Features
|
|
581
|
+
|
|
582
|
+
* ci-3111 media queries on clips sources ([856bd45](https://github.com/Financial-Times/cp-content-pipeline/commit/856bd457ba6dc56f292c6a31e0edfe3f29b4a904))
|
|
583
|
+
|
|
584
|
+
|
|
585
|
+
### Dependencies
|
|
586
|
+
|
|
587
|
+
* The following workspace dependencies were updated
|
|
588
|
+
* devDependencies
|
|
589
|
+
* @financial-times/cp-content-pipeline-client bumped from ^4.19.0 to ^4.20.0
|
|
590
|
+
* @financial-times/cp-content-pipeline-schema bumped from ^3.18.0 to ^3.19.0
|
|
591
|
+
|
|
592
|
+
## [9.10.0](https://github.com/Financial-Times/cp-content-pipeline/compare/cp-content-pipeline-ui-v9.9.0...cp-content-pipeline-ui-v9.10.0) (2025-11-06)
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
### Features
|
|
596
|
+
|
|
597
|
+
* ci-3143 support multiple authors opinion topper ([f71ee09](https://github.com/Financial-Times/cp-content-pipeline/commit/f71ee09098acbcbd9c6f141757970b741db69586))
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
### Dependencies
|
|
601
|
+
|
|
602
|
+
* The following workspace dependencies were updated
|
|
603
|
+
* devDependencies
|
|
604
|
+
* @financial-times/cp-content-pipeline-client bumped from ^4.18.0 to ^4.19.0
|
|
605
|
+
* @financial-times/cp-content-pipeline-schema bumped from ^3.17.0 to ^3.18.0
|
|
606
|
+
* @financial-times/cp-content-pipeline-styles bumped from ^4.4.0 to ^4.5.0
|
|
607
|
+
|
|
577
608
|
## [9.9.0](https://github.com/Financial-Times/cp-content-pipeline/compare/cp-content-pipeline-ui-v9.8.0...cp-content-pipeline-ui-v9.9.0) (2025-11-04)
|
|
578
609
|
|
|
579
610
|
|
|
@@ -2,9 +2,9 @@ import React from 'react';
|
|
|
2
2
|
import type { ConceptFragment, TopperFragment } from '@financial-times/cp-content-pipeline-client';
|
|
3
3
|
import { FollowButtonSlot } from './FollowButtonSlot';
|
|
4
4
|
type ColumnistProps = {
|
|
5
|
-
|
|
5
|
+
authorConcepts: ConceptFragment[];
|
|
6
6
|
followButtonVariant?: TopperFragment['followButtonVariant'];
|
|
7
7
|
followButtonSlot?: FollowButtonSlot;
|
|
8
8
|
};
|
|
9
|
-
declare const
|
|
10
|
-
export default
|
|
9
|
+
declare const Columnists: React.FC<ColumnistProps>;
|
|
10
|
+
export default Columnists;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const Columnists = ({ authorConcepts, followButtonVariant, followButtonSlot, }) => {
|
|
8
|
+
return (react_1.default.createElement("div", { className: "o-topper__columnist" },
|
|
9
|
+
react_1.default.createElement("ul", { className: "o-topper__columnist-list" }, authorConcepts.map((author) => {
|
|
10
|
+
return (react_1.default.createElement("li", null,
|
|
11
|
+
react_1.default.createElement("a", { className: "o-topper__columnist-name n-content-tag--with-follow", href: author.relativeUrl ?? undefined, "data-trackable": "columnist" }, author.prefLabel),
|
|
12
|
+
authorConcepts.length === 1 &&
|
|
13
|
+
followButtonSlot &&
|
|
14
|
+
followButtonSlot({
|
|
15
|
+
conceptId: author.id,
|
|
16
|
+
conceptName: author.prefLabel,
|
|
17
|
+
variant: followButtonVariant ?? 'standard',
|
|
18
|
+
})));
|
|
19
|
+
}))));
|
|
20
|
+
};
|
|
21
|
+
exports.default = Columnists;
|
|
22
|
+
//# sourceMappingURL=Columnists.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Columnists.js","sourceRoot":"","sources":["../../../src/components/Topper/Columnists.tsx"],"names":[],"mappings":";;;;;AAAA,kDAAyB;AAezB,MAAM,UAAU,GAA6B,CAAC,EAC5C,cAAc,EACd,mBAAmB,EACnB,gBAAgB,GACjB,EAAE,EAAE;IACH,OAAO,CACL,uCAAK,SAAS,EAAC,qBAAqB;QAClC,sCAAI,SAAS,EAAC,0BAA0B,IACrC,cAAc,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YAC7B,OAAO,CACL;gBACE,qCACE,SAAS,EAAC,qDAAqD,EAC/D,IAAI,EAAE,MAAM,CAAC,WAAW,IAAI,SAAS,oBACtB,WAAW,IAEzB,MAAM,CAAC,SAAS,CACf;gBAEH,cAAc,CAAC,MAAM,KAAK,CAAC;oBAC1B,gBAAgB;oBAChB,gBAAgB,CAAC;wBACf,SAAS,EAAE,MAAM,CAAC,EAAE;wBACpB,WAAW,EAAE,MAAM,CAAC,SAAS;wBAC7B,OAAO,EAAE,mBAAmB,IAAI,UAAU;qBAC3C,CAAC,CACD,CACN,CAAA;QACH,CAAC,CAAC,CACC,CACD,CACP,CAAA;AACH,CAAC,CAAA;AAED,kBAAe,UAAU,CAAA"}
|
|
@@ -7,7 +7,7 @@ type TagsProps = {
|
|
|
7
7
|
displayConcept?: ConceptFragment;
|
|
8
8
|
genreConcept?: ConceptFragment;
|
|
9
9
|
brandConcept?: ConceptFragment;
|
|
10
|
-
|
|
10
|
+
hasColumnists?: boolean;
|
|
11
11
|
followButtonVariant?: TopperFragment['followButtonVariant'];
|
|
12
12
|
FollowButtonSlot?: FollowButtonSlot;
|
|
13
13
|
headshot?: string;
|
|
@@ -4,11 +4,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const react_1 = __importDefault(require("react"));
|
|
7
|
-
const Tags = ({ __typename, isPackage, displayConcept, genreConcept, brandConcept,
|
|
7
|
+
const Tags = ({ __typename, isPackage, displayConcept, genreConcept, brandConcept, hasColumnists, followButtonVariant, headshot, FollowButtonSlot, }) => {
|
|
8
8
|
const isOpinion = __typename === 'OpinionTopper';
|
|
9
9
|
const concept = getConcept(displayConcept, genreConcept);
|
|
10
10
|
const baseFollowButtonCondition = FollowButtonSlot && concept?.id;
|
|
11
|
-
const additionalFollowButtonCondition = (isOpinion && !headshot && !
|
|
11
|
+
const additionalFollowButtonCondition = (isOpinion && !headshot && !hasColumnists) || !isOpinion;
|
|
12
12
|
const followButtonCondition = baseFollowButtonCondition && additionalFollowButtonCondition;
|
|
13
13
|
return (react_1.default.createElement("div", { className: "o-topper__tags" }, isPackage && brandConcept?.id ? (react_1.default.createElement(ConceptLabel, { ...brandConcept })) : (!isPackage && (react_1.default.createElement("div", { className: "topper__primary-theme" },
|
|
14
14
|
isOpinion && (react_1.default.createElement("span", { className: "o-topper__opinion-genre", "aria-label": "opinion article" }, `Opinion `)),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tags.js","sourceRoot":"","sources":["../../../src/components/Topper/Tags.tsx"],"names":[],"mappings":";;;;;AAAA,kDAAyB;AAoBzB,MAAM,IAAI,GAAwB,CAAC,EACjC,UAAU,EACV,SAAS,EACT,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,
|
|
1
|
+
{"version":3,"file":"Tags.js","sourceRoot":"","sources":["../../../src/components/Topper/Tags.tsx"],"names":[],"mappings":";;;;;AAAA,kDAAyB;AAoBzB,MAAM,IAAI,GAAwB,CAAC,EACjC,UAAU,EACV,SAAS,EACT,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,QAAQ,EACR,gBAAgB,GACjB,EAAE,EAAE;IACH,MAAM,SAAS,GAAG,UAAU,KAAK,eAAe,CAAA;IAChD,MAAM,OAAO,GAAG,UAAU,CAAC,cAAc,EAAE,YAAY,CAAC,CAAA;IACxD,MAAM,yBAAyB,GAAG,gBAAgB,IAAI,OAAO,EAAE,EAAE,CAAA;IACjE,MAAM,+BAA+B,GACnC,CAAC,SAAS,IAAI,CAAC,QAAQ,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAA;IAC1D,MAAM,qBAAqB,GACzB,yBAAyB,IAAI,+BAA+B,CAAA;IAE9D,OAAO,CACL,uCAAK,SAAS,EAAC,gBAAgB,IAC5B,SAAS,IAAI,YAAY,EAAE,EAAE,CAAC,CAAC,CAAC,CAC/B,8BAAC,YAAY,OAAK,YAAY,GAAI,CACnC,CAAC,CAAC,CAAC,CACF,CAAC,SAAS,IAAI,CACZ,uCAAK,SAAS,EAAC,uBAAuB;QACnC,SAAS,IAAI,CACZ,wCACE,SAAS,EAAC,yBAAyB,gBACxB,iBAAiB,IAE3B,UAAU,CACN,CACR;QAEA,YAAY,IAAI,8BAAC,YAAY,OAAK,YAAY,GAAI;QAElD,OAAO,IAAI,CACV;YACE,8BAAC,YAAY,OAAK,OAAO,GAAI,CACxB,CACR;QACA,qBAAqB,IAAI,CACxB,8BAAC,gBAAgB,IACf,SAAS,EAAE,OAAO,CAAC,EAAE,EACrB,WAAW,EAAE,OAAO,CAAC,SAAS,EAC9B,OAAO,EAAE,mBAAmB,IAAI,UAAU,GAC1C,CACH,CACG,CACP,CACF,CACG,CACP,CAAA;AACH,CAAC,CAAA;AAED,SAAS,UAAU,CACjB,cAA2C,EAC3C,YAAyC;IAEzC,IAAI,cAAc,EAAE,EAAE,EAAE,CAAC;QACvB,OAAO,cAAc,CAAA;IACvB,CAAC;SAAM,IAAI,YAAY,EAAE,EAAE,EAAE,CAAC;QAC5B,OAAO,YAAY,CAAA;IACrB,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,YAAY,GAA8B,CAAC,OAAO,EAAE,EAAE;IAC1D,OAAO,CACL,qCACE,IAAI,EAAE,OAAO,CAAC,WAAW,IAAI,SAAS,EACtC,SAAS,EAAC,iBAAiB,oBACZ,eAAe,gBAClB,eAAe,OAAO,CAAC,SAAS,SAAS;QAEpD,OAAO,CAAC,SAAS;kBAChB,CACL,CAAA;AACH,CAAC,CAAA;AAED,MAAM,YAAY,GAA8B,CAAC,OAAO,EAAE,EAAE;IAC1D,OAAO,CACL,qCACE,IAAI,EAAE,OAAO,CAAC,WAAW,EACzB,SAAS,EAAC,6DAA6D,oBACxD,eAAe,gBAClB,sBAAsB,OAAO,CAAC,SAAS,EAAE,qBACpC,OAAO,CAAC,EAAE,IAE1B,OAAO,CAAC,SAAS,CAChB,CACL,CAAA;AACH,CAAC,CAAA;AAED,kBAAe,IAAI,CAAA"}
|
|
@@ -33,7 +33,7 @@ const Headline_1 = __importDefault(require("./Headline"));
|
|
|
33
33
|
const Intro_1 = __importDefault(require("./Intro"));
|
|
34
34
|
const Picture_1 = __importDefault(require("./Picture"));
|
|
35
35
|
const Headshot_1 = __importDefault(require("../Headshot"));
|
|
36
|
-
const
|
|
36
|
+
const Columnists_1 = __importDefault(require("./Columnists"));
|
|
37
37
|
const LiveBlogIndicator_1 = __importDefault(require("./LiveBlogIndicator"));
|
|
38
38
|
const Flourish_1 = __importDefault(require("../content-tree/Flourish"));
|
|
39
39
|
const classnames_1 = __importDefault(require("classnames"));
|
|
@@ -62,7 +62,16 @@ const Topper = ({ content, slot, followButtonSlot, showPremiumLabel = false, rea
|
|
|
62
62
|
const hasLayoutWidth = 'layoutWidth' in topper && topper.layoutWidth;
|
|
63
63
|
const hasDesign = 'design' in topper && topper.design;
|
|
64
64
|
const hasHeadshot = 'headshot' in topper && topper.headshot;
|
|
65
|
-
const
|
|
65
|
+
const hasColumnists = 'columnists' in topper &&
|
|
66
|
+
!!topper.columnists &&
|
|
67
|
+
topper.columnists.length > 0;
|
|
68
|
+
const legacyHasColumnist = 'columnist' in topper && !!topper.columnist; // @deprecated Replaced with usage of `columinists`
|
|
69
|
+
const hasOneColumnist = (hasColumnists && topper.columnists.length === 1) || legacyHasColumnist;
|
|
70
|
+
const oneColumnist = hasOneColumnist
|
|
71
|
+
? hasColumnists
|
|
72
|
+
? topper.columnists[0]
|
|
73
|
+
: topper.columnist
|
|
74
|
+
: null;
|
|
66
75
|
const sponsorName = 'clientName' in content && content.clientName;
|
|
67
76
|
const disclaimerType = isArticle ? content.disclaimerType : undefined;
|
|
68
77
|
const modifiers = [];
|
|
@@ -74,8 +83,8 @@ const Topper = ({ content, slot, followButtonSlot, showPremiumLabel = false, rea
|
|
|
74
83
|
slot && modifiers.push('right-rail');
|
|
75
84
|
hasLayoutWidth &&
|
|
76
85
|
modifiers.push(topper.layoutWidth === 'full-grid' ? 'full-grid' : 'in-line');
|
|
77
|
-
const headshotAltText = isOpinion &&
|
|
78
|
-
? `Headshot for ${
|
|
86
|
+
const headshotAltText = isOpinion && oneColumnist
|
|
87
|
+
? `Headshot for ${oneColumnist.prefLabel}`
|
|
79
88
|
: isPodcast
|
|
80
89
|
? 'Cover photo for podcast'
|
|
81
90
|
: '';
|
|
@@ -108,7 +117,7 @@ const Topper = ({ content, slot, followButtonSlot, showPremiumLabel = false, rea
|
|
|
108
117
|
'o-topper__content--background-box': topper.backgroundBox,
|
|
109
118
|
}), id: "o-topper" },
|
|
110
119
|
isLiveBlog ? (react_1.default.createElement("div", { className: "o-topper__tags" },
|
|
111
|
-
react_1.default.createElement(LiveBlogIndicator_1.default, { realtime: content.realtime ?? undefined, lastUpdatedDateTime: getMostRecentPostPublishedDate() }))) : (react_1.default.createElement(Tags_1.default, { __typename: topper.__typename, isPackage: isPackage, displayConcept: topper.displayConcept ?? undefined, brandConcept: ('brandConcept' in topper && topper.brandConcept) || undefined, genreConcept: ('genreConcept' in topper && topper.genreConcept) || undefined, headshot: hasHeadshot || undefined,
|
|
120
|
+
react_1.default.createElement(LiveBlogIndicator_1.default, { realtime: content.realtime ?? undefined, lastUpdatedDateTime: getMostRecentPostPublishedDate() }))) : (react_1.default.createElement(Tags_1.default, { __typename: topper.__typename, isPackage: isPackage, displayConcept: topper.displayConcept ?? undefined, brandConcept: ('brandConcept' in topper && topper.brandConcept) || undefined, genreConcept: ('genreConcept' in topper && topper.genreConcept) || undefined, headshot: hasHeadshot || undefined, hasColumnists: hasColumnists, followButtonVariant: topper.followButtonVariant, FollowButtonSlot: followButtonSlot })),
|
|
112
121
|
react_1.default.createElement(Headline_1.default, { headline: topper.headline, showPremiumLabel: showPremiumLabel && content.accessLevel === 'premium', isLargeHeadline: ('isLargeHeadline' in topper && topper.isLargeHeadline) ??
|
|
113
122
|
undefined }),
|
|
114
123
|
isLiveBlog && isFlourish ? (react_1.default.createElement(Flourish_1.default, { content: {
|
|
@@ -119,9 +128,9 @@ const Topper = ({ content, slot, followButtonSlot, showPremiumLabel = false, rea
|
|
|
119
128
|
fallbackImage: topper.leadFlourish.fallbackImage ?? undefined,
|
|
120
129
|
}, iFrame: true, inArticleBody: false })) : (''),
|
|
121
130
|
topper.intro && (react_1.default.createElement(Intro_1.default, { structured: topper.intro.structured, source: topper.intro.source })),
|
|
122
|
-
hasHeadshot && !isAudio && isOpinion &&
|
|
123
|
-
react_1.default.createElement(Headshot_1.default, { headshot: topper.headshot, prefLabel:
|
|
124
|
-
isOpinion &&
|
|
131
|
+
hasHeadshot && !isAudio && isOpinion && oneColumnist && (react_1.default.createElement("div", { className: "o-topper__headshot" },
|
|
132
|
+
react_1.default.createElement(Headshot_1.default, { headshot: topper.headshot, prefLabel: oneColumnist.prefLabel, className: 'o-topper__headshot-image', altText: headshotAltText }))),
|
|
133
|
+
isOpinion && hasColumnists && (react_1.default.createElement(Columnists_1.default, { authorConcepts: [...topper.columnists], followButtonVariant: topper.followButtonVariant, followButtonSlot: followButtonSlot }))),
|
|
125
134
|
readNextSlot && (react_1.default.createElement("div", { className: "o-topper__read-next" }, readNextSlot())),
|
|
126
135
|
react_1.default.createElement("div", { className: "o-topper__background" }),
|
|
127
136
|
'images' in topper && react_1.default.createElement(Picture_1.default, { topper: topper })))));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/Topper/index.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAqD;AACrD,wDAA+B;AAC/B,kDAAyB;AACzB,0DAAiC;AACjC,oDAA2B;AAC3B,wDAA+B;AAC/B,2DAAkC;AAClC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/Topper/index.tsx"],"names":[],"mappings":"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"}
|
|
@@ -7,16 +7,45 @@ exports.ClipTag = void 0;
|
|
|
7
7
|
const react_1 = __importDefault(require("react"));
|
|
8
8
|
const index_1 = require("./index");
|
|
9
9
|
const FixedAspectRatio_1 = require("../../../FixedAspectRatio/FixedAspectRatio");
|
|
10
|
-
const ClipTag = ({ id, dataLayout, description, poster, autoplay, noAudio, loop, muted, clip, credits, caption, accessibility, preload, noDescription = false, noInfoBox = false, noCaption = false, dataTrackable, systemTitle, }) => {
|
|
10
|
+
const ClipTag = ({ id, dataLayout, description, poster, autoplay, noAudio, loop, muted, clip, credits, caption, accessibility, preload, noDescription = false, noInfoBox = false, noCaption = false, maxClipWidth = 0, dataTrackable, systemTitle, }) => {
|
|
11
11
|
const { pixelWidth, pixelHeight } = clip?.dataSource?.[0]
|
|
12
12
|
? clip.dataSource[0]
|
|
13
13
|
: { pixelWidth: 0, pixelHeight: 0 };
|
|
14
|
+
const mediaQuery = ({ dppx, previousSourceWidth, }) => {
|
|
15
|
+
const mqOptions = [];
|
|
16
|
+
if (dppx && dppx > 1) {
|
|
17
|
+
mqOptions.push(`(min-resolution: ${dppx}dppx)`);
|
|
18
|
+
}
|
|
19
|
+
if (previousSourceWidth) {
|
|
20
|
+
mqOptions.push(`(min-width: ${previousSourceWidth}px)`);
|
|
21
|
+
}
|
|
22
|
+
if (mqOptions.length > 0) {
|
|
23
|
+
return mqOptions.join(' and ');
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
// get the index of the last source that is a video
|
|
27
|
+
const getLastVideoIndex = () => {
|
|
28
|
+
for (let i = clip?.dataSource.length - 1; i >= 0; i--) {
|
|
29
|
+
if (clip?.dataSource[i]?.mediaType.startsWith('video/')) {
|
|
30
|
+
return i;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return 0;
|
|
34
|
+
};
|
|
35
|
+
const lastVideoIndex = getLastVideoIndex();
|
|
14
36
|
return (react_1.default.createElement("div", { "data-cp-clip-layout": dataLayout, "data-cp-clip-poster": poster, "data-cp-clip-autoplay": autoplay, "data-cp-clip-no-audio": noAudio, "data-cp-clip-no-description": noDescription, "data-cp-clip-caption": caption, "data-cp-clip-no-info-box": noInfoBox, "data-cp-clip-no-caption": noCaption, "data-cp-clip-closed-caption": Boolean(accessibility?.captions?.[0]?.url), "data-cp-clip-loop": loop, className: "cp-clip", "data-trackable": dataTrackable, "data-o-component": "cp-clip", "data-cp-clip-id": id, "data-cp-clip-system-title": systemTitle },
|
|
15
37
|
!noInfoBox && react_1.default.createElement(index_1.VideoInfoBox, null),
|
|
16
38
|
react_1.default.createElement("div", { className: "cp-clip__video-container" },
|
|
17
39
|
react_1.default.createElement(FixedAspectRatio_1.FixedAspectRatio, { width: pixelWidth, height: pixelHeight, element: "video", className: "cp-clip__video", controls: true, controlsList: "nodownload noremoteplayback noplaybackrate", disablePictureInPicture: true, disableRemotePlayback: true, playsInline: true, muted: muted, loop: loop, poster: poster, preload: preload, id: `clip-${id}`, crossOrigin: "anonymous" },
|
|
18
|
-
clip?.dataSource?.map(({ binaryUrl, mediaType }, index) => {
|
|
19
|
-
|
|
40
|
+
clip?.dataSource?.map(({ binaryUrl, mediaType, dppx, previousSourceWidth }, index) => {
|
|
41
|
+
// allow user to set a max width for clip sources to avoid loading very large videos on places like the homepage
|
|
42
|
+
if (maxClipWidth &&
|
|
43
|
+
previousSourceWidth &&
|
|
44
|
+
previousSourceWidth > maxClipWidth &&
|
|
45
|
+
index < lastVideoIndex) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
return (react_1.default.createElement("source", { id: `video-source-${index}-${id}`, "data-cp-component": "cp-clip__video-source", src: binaryUrl, type: mediaType !== '' ? mediaType : undefined, key: binaryUrl, media: mediaQuery({ dppx, previousSourceWidth }) }));
|
|
20
49
|
}),
|
|
21
50
|
react_1.default.createElement(index_1.ClosedCaptions, { accessibility: accessibility }))),
|
|
22
51
|
(!noDescription || !noCaption) && (react_1.default.createElement("div", { className: "cp-clip__video-meta-info", "data-cp-clip-video-meta-info": true },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClipTag.js","sourceRoot":"","sources":["../../../../../src/components/content-tree/Clip/components/ClipTag.tsx"],"names":[],"mappings":";;;;;;AAAA,kDAAyB;AACzB,mCAKgB;AAChB,iFAA6E;
|
|
1
|
+
{"version":3,"file":"ClipTag.js","sourceRoot":"","sources":["../../../../../src/components/content-tree/Clip/components/ClipTag.tsx"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const react_1 = __importDefault(require("react"));
|
|
7
7
|
const components_1 = require("../components");
|
|
8
|
-
const ClipComponent = ({ content, preset = 'full-player', preload = 'auto', }) => {
|
|
8
|
+
const ClipComponent = ({ content, preset = 'full-player', preload = 'auto', maxClipWidth = 0, }) => {
|
|
9
9
|
let poster = 'poster' in content ? content.poster : '';
|
|
10
10
|
let id;
|
|
11
11
|
// We support currently a single clip, with multiple sources.
|
|
@@ -36,11 +36,11 @@ const ClipComponent = ({ content, preset = 'full-player', preload = 'auto', }) =
|
|
|
36
36
|
const accessibility = content.accessibility ?? {};
|
|
37
37
|
const systemTitle = content.systemTitle ?? '';
|
|
38
38
|
if (preset === 'thumbnail') {
|
|
39
|
-
return (react_1.default.createElement(components_1.ClipTag, { id: id, clip: clip, poster: poster, accessibility: accessibility, autoplay: content.autoplay, loop: content.loop, noAudio: noAudio, muted: content.muted, preload: preload, noCaption: true, noDescription: true, noInfoBox: true, systemTitle: systemTitle }));
|
|
39
|
+
return (react_1.default.createElement(components_1.ClipTag, { id: id, clip: clip, poster: poster, accessibility: accessibility, autoplay: content.autoplay, loop: content.loop, noAudio: noAudio, muted: content.muted, preload: preload, noCaption: true, noDescription: true, noInfoBox: true, systemTitle: systemTitle, maxClipWidth: maxClipWidth }));
|
|
40
40
|
}
|
|
41
41
|
return (react_1.default.createElement(components_1.ContentLayout, { dataLayout: content.dataLayout },
|
|
42
42
|
react_1.default.createElement(components_1.Container, { dataLayout: content.dataLayout },
|
|
43
|
-
react_1.default.createElement(components_1.ClipTag, { id: id, dataLayout: content.dataLayout, description: content.description ?? '', poster: posterAttribute, autoplay: content.autoplay, noAudio: noAudio, loop: content.loop, muted: content.muted, clip: clip, credits: content.credits ?? '', caption: content.caption ?? '', systemTitle: systemTitle, accessibility: accessibility, preload: preload, dataTrackable: "next-article-cp-clip" }))));
|
|
43
|
+
react_1.default.createElement(components_1.ClipTag, { id: id, dataLayout: content.dataLayout, description: content.description ?? '', poster: posterAttribute, autoplay: content.autoplay, noAudio: noAudio, loop: content.loop, muted: content.muted, clip: clip, credits: content.credits ?? '', caption: content.caption ?? '', systemTitle: systemTitle, accessibility: accessibility, preload: preload, dataTrackable: "next-article-cp-clip", maxClipWidth: maxClipWidth }))));
|
|
44
44
|
};
|
|
45
45
|
exports.default = ClipComponent;
|
|
46
46
|
//# sourceMappingURL=component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.js","sourceRoot":"","sources":["../../../../../src/components/content-tree/Clip/template/component.tsx"],"names":[],"mappings":";;;;;AAAA,kDAAyB;AACzB,8CAAiE;
|
|
1
|
+
{"version":3,"file":"component.js","sourceRoot":"","sources":["../../../../../src/components/content-tree/Clip/template/component.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@financial-times/cp-content-pipeline-ui",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.11.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
"@babel/preset-env": "^7.22.5",
|
|
17
17
|
"@babel/preset-react": "^7.22.5",
|
|
18
18
|
"@financial-times/content-tree": "github:financial-times/content-tree#3f77ec4",
|
|
19
|
-
"@financial-times/cp-content-pipeline-client": "^4.
|
|
20
|
-
"@financial-times/cp-content-pipeline-schema": "^3.
|
|
21
|
-
"@financial-times/cp-content-pipeline-styles": "^4.
|
|
19
|
+
"@financial-times/cp-content-pipeline-client": "^4.20.0",
|
|
20
|
+
"@financial-times/cp-content-pipeline-schema": "^3.19.0",
|
|
21
|
+
"@financial-times/cp-content-pipeline-styles": "^4.5.0",
|
|
22
22
|
"@financial-times/n-scrollytelling-image": "^1.1.0",
|
|
23
23
|
"@financial-times/o-grid": "^6.1.8",
|
|
24
24
|
"@financial-times/o-share": "^11.0.0",
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
ConceptFragment,
|
|
5
|
+
TopperFragment,
|
|
6
|
+
} from '@financial-times/cp-content-pipeline-client'
|
|
7
|
+
|
|
8
|
+
import { FollowButtonSlot } from './FollowButtonSlot'
|
|
9
|
+
|
|
10
|
+
type ColumnistProps = {
|
|
11
|
+
authorConcepts: ConceptFragment[]
|
|
12
|
+
followButtonVariant?: TopperFragment['followButtonVariant']
|
|
13
|
+
followButtonSlot?: FollowButtonSlot
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const Columnists: React.FC<ColumnistProps> = ({
|
|
17
|
+
authorConcepts,
|
|
18
|
+
followButtonVariant,
|
|
19
|
+
followButtonSlot,
|
|
20
|
+
}) => {
|
|
21
|
+
return (
|
|
22
|
+
<div className="o-topper__columnist">
|
|
23
|
+
<ul className="o-topper__columnist-list">
|
|
24
|
+
{authorConcepts.map((author) => {
|
|
25
|
+
return (
|
|
26
|
+
<li>
|
|
27
|
+
<a
|
|
28
|
+
className="o-topper__columnist-name n-content-tag--with-follow"
|
|
29
|
+
href={author.relativeUrl ?? undefined}
|
|
30
|
+
data-trackable="columnist"
|
|
31
|
+
>
|
|
32
|
+
{author.prefLabel}
|
|
33
|
+
</a>
|
|
34
|
+
{/* Only show follow button if there's a single author */}
|
|
35
|
+
{authorConcepts.length === 1 &&
|
|
36
|
+
followButtonSlot &&
|
|
37
|
+
followButtonSlot({
|
|
38
|
+
conceptId: author.id,
|
|
39
|
+
conceptName: author.prefLabel,
|
|
40
|
+
variant: followButtonVariant ?? 'standard',
|
|
41
|
+
})}
|
|
42
|
+
</li>
|
|
43
|
+
)
|
|
44
|
+
})}
|
|
45
|
+
</ul>
|
|
46
|
+
</div>
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export default Columnists
|
|
@@ -12,7 +12,7 @@ type TagsProps = {
|
|
|
12
12
|
displayConcept?: ConceptFragment
|
|
13
13
|
genreConcept?: ConceptFragment
|
|
14
14
|
brandConcept?: ConceptFragment
|
|
15
|
-
|
|
15
|
+
hasColumnists?: boolean
|
|
16
16
|
followButtonVariant?: TopperFragment['followButtonVariant']
|
|
17
17
|
FollowButtonSlot?: FollowButtonSlot
|
|
18
18
|
headshot?: string
|
|
@@ -24,7 +24,7 @@ const Tags: React.FC<TagsProps> = ({
|
|
|
24
24
|
displayConcept,
|
|
25
25
|
genreConcept,
|
|
26
26
|
brandConcept,
|
|
27
|
-
|
|
27
|
+
hasColumnists,
|
|
28
28
|
followButtonVariant,
|
|
29
29
|
headshot,
|
|
30
30
|
FollowButtonSlot,
|
|
@@ -33,7 +33,7 @@ const Tags: React.FC<TagsProps> = ({
|
|
|
33
33
|
const concept = getConcept(displayConcept, genreConcept)
|
|
34
34
|
const baseFollowButtonCondition = FollowButtonSlot && concept?.id
|
|
35
35
|
const additionalFollowButtonCondition =
|
|
36
|
-
(isOpinion && !headshot && !
|
|
36
|
+
(isOpinion && !headshot && !hasColumnists) || !isOpinion
|
|
37
37
|
const followButtonCondition =
|
|
38
38
|
baseFollowButtonCondition && additionalFollowButtonCondition
|
|
39
39
|
|
|
@@ -5,7 +5,7 @@ import Headline from './Headline'
|
|
|
5
5
|
import Intro from './Intro'
|
|
6
6
|
import Picture from './Picture'
|
|
7
7
|
import Headshot from '../Headshot'
|
|
8
|
-
import
|
|
8
|
+
import Columnists from './Columnists'
|
|
9
9
|
import LiveBlogIndicator from './LiveBlogIndicator'
|
|
10
10
|
import { FollowButtonSlot } from './FollowButtonSlot'
|
|
11
11
|
import Flourish from '../content-tree/Flourish'
|
|
@@ -65,7 +65,18 @@ const Topper: React.FC<TopperProps> = ({
|
|
|
65
65
|
const hasLayoutWidth = 'layoutWidth' in topper && topper.layoutWidth
|
|
66
66
|
const hasDesign = 'design' in topper && topper.design
|
|
67
67
|
const hasHeadshot = 'headshot' in topper && topper.headshot
|
|
68
|
-
const
|
|
68
|
+
const hasColumnists =
|
|
69
|
+
'columnists' in topper &&
|
|
70
|
+
!!topper.columnists &&
|
|
71
|
+
topper.columnists.length > 0
|
|
72
|
+
const legacyHasColumnist = 'columnist' in topper && !!topper.columnist // @deprecated Replaced with usage of `columinists`
|
|
73
|
+
const hasOneColumnist =
|
|
74
|
+
(hasColumnists && topper.columnists.length === 1) || legacyHasColumnist
|
|
75
|
+
const oneColumnist = hasOneColumnist
|
|
76
|
+
? hasColumnists
|
|
77
|
+
? topper.columnists[0]
|
|
78
|
+
: topper.columnist
|
|
79
|
+
: null
|
|
69
80
|
const sponsorName = 'clientName' in content && content.clientName
|
|
70
81
|
const disclaimerType = isArticle ? content.disclaimerType : undefined
|
|
71
82
|
|
|
@@ -81,8 +92,8 @@ const Topper: React.FC<TopperProps> = ({
|
|
|
81
92
|
modifiers.push(topper.layoutWidth === 'full-grid' ? 'full-grid' : 'in-line')
|
|
82
93
|
|
|
83
94
|
const headshotAltText =
|
|
84
|
-
isOpinion &&
|
|
85
|
-
? `Headshot for ${
|
|
95
|
+
isOpinion && oneColumnist
|
|
96
|
+
? `Headshot for ${oneColumnist.prefLabel}`
|
|
86
97
|
: isPodcast
|
|
87
98
|
? 'Cover photo for podcast'
|
|
88
99
|
: ''
|
|
@@ -161,7 +172,7 @@ const Topper: React.FC<TopperProps> = ({
|
|
|
161
172
|
('genreConcept' in topper && topper.genreConcept) || undefined
|
|
162
173
|
}
|
|
163
174
|
headshot={hasHeadshot || undefined}
|
|
164
|
-
|
|
175
|
+
hasColumnists={hasColumnists}
|
|
165
176
|
followButtonVariant={topper.followButtonVariant}
|
|
166
177
|
FollowButtonSlot={followButtonSlot}
|
|
167
178
|
/>
|
|
@@ -197,19 +208,19 @@ const Topper: React.FC<TopperProps> = ({
|
|
|
197
208
|
source={topper.intro.source}
|
|
198
209
|
/>
|
|
199
210
|
)}
|
|
200
|
-
{hasHeadshot && !isAudio && isOpinion &&
|
|
211
|
+
{hasHeadshot && !isAudio && isOpinion && oneColumnist && (
|
|
201
212
|
<div className="o-topper__headshot">
|
|
202
213
|
<Headshot
|
|
203
214
|
headshot={topper.headshot}
|
|
204
|
-
prefLabel={
|
|
215
|
+
prefLabel={oneColumnist.prefLabel}
|
|
205
216
|
className={'o-topper__headshot-image'}
|
|
206
217
|
altText={headshotAltText}
|
|
207
218
|
/>
|
|
208
219
|
</div>
|
|
209
220
|
)}
|
|
210
|
-
{isOpinion &&
|
|
211
|
-
<
|
|
212
|
-
|
|
221
|
+
{isOpinion && hasColumnists && (
|
|
222
|
+
<Columnists
|
|
223
|
+
authorConcepts={[...topper.columnists]}
|
|
213
224
|
followButtonVariant={topper.followButtonVariant}
|
|
214
225
|
followButtonSlot={followButtonSlot}
|
|
215
226
|
/>
|
|
@@ -21,6 +21,7 @@ interface ClipTagProps {
|
|
|
21
21
|
noDescription?: boolean
|
|
22
22
|
noInfoBox?: boolean
|
|
23
23
|
noCaption?: boolean
|
|
24
|
+
maxClipWidth?: number
|
|
24
25
|
noClosedCaption?: boolean
|
|
25
26
|
accessibility?: ComponentWorkarounds.ClipAccessibility
|
|
26
27
|
muted?: boolean
|
|
@@ -47,6 +48,7 @@ export const ClipTag: React.FC<ClipTagProps> = ({
|
|
|
47
48
|
noDescription = false,
|
|
48
49
|
noInfoBox = false,
|
|
49
50
|
noCaption = false,
|
|
51
|
+
maxClipWidth = 0,
|
|
50
52
|
dataTrackable,
|
|
51
53
|
systemTitle,
|
|
52
54
|
}) => {
|
|
@@ -54,6 +56,37 @@ export const ClipTag: React.FC<ClipTagProps> = ({
|
|
|
54
56
|
? clip.dataSource[0]
|
|
55
57
|
: { pixelWidth: 0, pixelHeight: 0 }
|
|
56
58
|
|
|
59
|
+
const mediaQuery = ({
|
|
60
|
+
dppx,
|
|
61
|
+
previousSourceWidth,
|
|
62
|
+
}: {
|
|
63
|
+
dppx: number | null | undefined
|
|
64
|
+
previousSourceWidth: number | null | undefined
|
|
65
|
+
}) => {
|
|
66
|
+
const mqOptions = []
|
|
67
|
+
if (dppx && dppx > 1) {
|
|
68
|
+
mqOptions.push(`(min-resolution: ${dppx}dppx)`)
|
|
69
|
+
}
|
|
70
|
+
if (previousSourceWidth) {
|
|
71
|
+
mqOptions.push(`(min-width: ${previousSourceWidth}px)`)
|
|
72
|
+
}
|
|
73
|
+
if (mqOptions.length > 0) {
|
|
74
|
+
return mqOptions.join(' and ')
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// get the index of the last source that is a video
|
|
79
|
+
const getLastVideoIndex = (): number => {
|
|
80
|
+
for (let i = clip?.dataSource.length - 1; i >= 0; i--) {
|
|
81
|
+
if (clip?.dataSource[i]?.mediaType.startsWith('video/')) {
|
|
82
|
+
return i
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return 0
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const lastVideoIndex: number = getLastVideoIndex()
|
|
89
|
+
|
|
57
90
|
return (
|
|
58
91
|
<div
|
|
59
92
|
data-cp-clip-layout={dataLayout}
|
|
@@ -92,17 +125,31 @@ export const ClipTag: React.FC<ClipTagProps> = ({
|
|
|
92
125
|
id={`clip-${id}`}
|
|
93
126
|
crossOrigin="anonymous"
|
|
94
127
|
>
|
|
95
|
-
{clip?.dataSource?.map(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
128
|
+
{clip?.dataSource?.map(
|
|
129
|
+
({ binaryUrl, mediaType, dppx, previousSourceWidth }, index) => {
|
|
130
|
+
// allow user to set a max width for clip sources to avoid loading very large videos on places like the homepage
|
|
131
|
+
if (
|
|
132
|
+
maxClipWidth &&
|
|
133
|
+
previousSourceWidth &&
|
|
134
|
+
previousSourceWidth > maxClipWidth &&
|
|
135
|
+
index < lastVideoIndex
|
|
136
|
+
) {
|
|
137
|
+
return null
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return (
|
|
141
|
+
<source
|
|
142
|
+
id={`video-source-${index}-${id}`}
|
|
143
|
+
data-cp-component="cp-clip__video-source"
|
|
144
|
+
src={binaryUrl}
|
|
145
|
+
type={mediaType !== '' ? mediaType : undefined}
|
|
146
|
+
key={binaryUrl}
|
|
147
|
+
media={mediaQuery({ dppx, previousSourceWidth })}
|
|
148
|
+
></source>
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
)}
|
|
152
|
+
|
|
106
153
|
<ClosedCaptions accessibility={accessibility} />
|
|
107
154
|
</FixedAspectRatio>
|
|
108
155
|
</div>
|