@financial-times/cp-content-pipeline-ui 9.14.1 → 9.15.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.
Files changed (26) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/lib/components/Body/index.test.js +4 -0
  3. package/lib/components/Body/index.test.js.map +1 -1
  4. package/lib/components/RichText/index.js +3 -0
  5. package/lib/components/RichText/index.js.map +1 -1
  6. package/lib/components/RichText/index.test.js +2 -0
  7. package/lib/components/RichText/index.test.js.map +1 -1
  8. package/lib/components/content-tree/InNumbers/index.d.ts +9 -0
  9. package/lib/components/content-tree/InNumbers/index.js +28 -0
  10. package/lib/components/content-tree/InNumbers/index.js.map +1 -0
  11. package/lib/components/content-tree/YoutubeVideo/client/index.d.ts +18 -0
  12. package/lib/components/content-tree/YoutubeVideo/client/index.js +37 -0
  13. package/lib/components/content-tree/YoutubeVideo/client/index.js.map +1 -0
  14. package/lib/components/content-tree/YoutubeVideo/test/index.spec.d.ts +1 -0
  15. package/lib/components/content-tree/YoutubeVideo/test/index.spec.js +51 -0
  16. package/lib/components/content-tree/YoutubeVideo/test/index.spec.js.map +1 -0
  17. package/lib/main.scss +1 -0
  18. package/package.json +7 -5
  19. package/src/components/Body/index.test.tsx +4 -0
  20. package/src/components/RichText/index.test.tsx +5 -0
  21. package/src/components/RichText/index.tsx +3 -0
  22. package/src/components/content-tree/InNumbers/client/main.scss +51 -0
  23. package/src/components/content-tree/InNumbers/index.tsx +47 -0
  24. package/src/components/content-tree/YoutubeVideo/client/index.ts +60 -0
  25. package/src/components/content-tree/YoutubeVideo/test/index.spec.ts +59 -0
  26. package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md CHANGED
@@ -574,6 +574,29 @@
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.15.0](https://github.com/Financial-Times/cp-content-pipeline/compare/cp-content-pipeline-ui-v9.14.1...cp-content-pipeline-ui-v9.15.0) (2026-01-08)
578
+
579
+
580
+ ### Features
581
+
582
+ * in numbers component ([729021c](https://github.com/Financial-Times/cp-content-pipeline/commit/729021c08965f313163c3c092d40db6233352ba5))
583
+ * rendering embedded youtube videos ([26b631b](https://github.com/Financial-Times/cp-content-pipeline/commit/26b631ba1325e04936e98aa73574e23efa0b8c12))
584
+
585
+
586
+ ### Bug Fixes
587
+
588
+ * refactor YT embed rendering ([6565291](https://github.com/Financial-Times/cp-content-pipeline/commit/6565291c3303599909a39ede713d106586b10e23))
589
+ * remove init and loadYouTubeAPI ([9167266](https://github.com/Financial-Times/cp-content-pipeline/commit/9167266763e3c9fa40d0f3b4977f5eea2728d946))
590
+ * updating based on code comments ([e87e58e](https://github.com/Financial-Times/cp-content-pipeline/commit/e87e58ef5a617129a23fa4cd2d4ed426fdd2b560))
591
+
592
+
593
+ ### Dependencies
594
+
595
+ * The following workspace dependencies were updated
596
+ * devDependencies
597
+ * @financial-times/cp-content-pipeline-client bumped from ^4.21.0 to ^4.22.0
598
+ * @financial-times/cp-content-pipeline-schema bumped from ^3.22.0 to ^3.23.0
599
+
577
600
  ## [9.14.1](https://github.com/Financial-Times/cp-content-pipeline/compare/cp-content-pipeline-ui-v9.14.0...cp-content-pipeline-ui-v9.14.1) (2025-12-17)
578
601
 
579
602
 
@@ -106,13 +106,17 @@ const legacyOverridesToTest = [
106
106
  ];
107
107
  describe('Body', () => {
108
108
  let mockDate;
109
+ let warnSpy;
109
110
  beforeAll(() => {
110
111
  mockDate = jest
111
112
  .spyOn(Date.prototype, 'toLocaleString')
112
113
  .mockReturnValue('11/06/2024, 14:13:25');
114
+ // suppress warning that LiveBlogPackage is using legacy componentWillReceiveProps in x-interaction component
115
+ warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => { });
113
116
  });
114
117
  afterAll(() => {
115
118
  mockDate.mockRestore();
119
+ warnSpy.mockRestore();
116
120
  });
117
121
  describe('default renderers', () => {
118
122
  test.each(typesToTest)('renders default renderer for %s', (type) => {
@@ -1 +1 @@
1
- {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../../src/components/Body/index.test.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../../src/components/Body/index.test.tsx"],"names":[],"mappings":"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"}
@@ -49,6 +49,7 @@ const YoutubeVideo_1 = __importDefault(require("../content-tree/YoutubeVideo"));
49
49
  const CustomCodeComponent_1 = __importDefault(require("../content-tree/CustomCodeComponent"));
50
50
  const Timeline_1 = __importDefault(require("../content-tree/Timeline"));
51
51
  const TimelineEvent_1 = __importDefault(require("../content-tree/Timeline/TimelineEvent"));
52
+ const InNumbers_1 = __importStar(require("../content-tree/InNumbers"));
52
53
  const BasicComponents_1 = require("./BasicComponents");
53
54
  const context_1 = __importDefault(require("./context"));
54
55
  exports.ComponentsContext = (0, react_1.createContext)({});
@@ -99,6 +100,8 @@ const componentMap = {
99
100
  'youtube-video': YoutubeVideo_1.default,
100
101
  timeline: Timeline_1.default,
101
102
  'timeline-event': TimelineEvent_1.default,
103
+ 'in-numbers': InNumbers_1.default,
104
+ definition: InNumbers_1.Definition,
102
105
  };
103
106
  function isParentNode(node) {
104
107
  return 'children' in node;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/RichText/index.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/RichText/index.tsx"],"names":[],"mappings":"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"}
@@ -75,6 +75,7 @@ describe('<RichText />', () => {
75
75
  expect(react_1.createElement).toHaveBeenCalledWith(expect.any(Function), expect.objectContaining({ key: 1 }));
76
76
  });
77
77
  it("ignores components that it doesn't have a mapping for", () => {
78
+ jest.spyOn(console, 'warn').mockImplementation(() => { });
78
79
  const tree = {
79
80
  type: 'body',
80
81
  version: 1,
@@ -98,6 +99,7 @@ describe('<RichText />', () => {
98
99
  expect(getByText('i should render').tagName).toEqual('P');
99
100
  //wrapping component with react-testing-library is a div
100
101
  expect(getByText('i should not render').tagName).toEqual('DIV');
102
+ expect(console.warn).toHaveBeenCalledWith("couldn't find component for Content Tree node unknown, using fallback component instead (by default will render the node's children)");
101
103
  });
102
104
  it('adds references as props', () => {
103
105
  const tree = {
@@ -1 +1 @@
1
- {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../../src/components/RichText/index.test.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../../src/components/RichText/index.test.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { ContentTree } from '@financial-times/content-tree';
2
+ import React from 'react';
3
+ import { ContentProps } from '../../types';
4
+ interface InNumbersProps extends ContentProps<ContentTree.InNumbers> {
5
+ }
6
+ declare const Definition: React.FC<ContentProps<ContentTree.Definition>>;
7
+ declare const InNumbers: React.FC<React.PropsWithChildren<InNumbersProps>>;
8
+ export default InNumbers;
9
+ export { Definition };
@@ -0,0 +1,28 @@
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
+ exports.Definition = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const ContentLayout_1 = require("../../ContentLayout");
9
+ const Definition = ({ content: { term, description }, }) => {
10
+ return (react_1.default.createElement("div", { className: "cp-in-numbers__definition" },
11
+ react_1.default.createElement("dt", { className: "cp-in-numbers__term n-content-heading-3 o3-editorial-typography-subheading" }, term),
12
+ react_1.default.createElement("dd", { className: "cp-in-numbers__description" }, description)));
13
+ };
14
+ exports.Definition = Definition;
15
+ /*
16
+ * @description InNumbers component is used to render a list of numbers with a title.
17
+ * @param content.title - Optional heading for the numbers section.
18
+ * @param children - Rendered Definition components (passed by RichText).
19
+ */
20
+ const InNumbers = ({ content, children, }) => {
21
+ const { title } = content;
22
+ return (react_1.default.createElement(ContentLayout_1.ContentLayout, { dataLayout: "full-grid", dataComponent: "cp-in-numbers" },
23
+ react_1.default.createElement("div", { className: "cp-in-numbers", "data-trackable": "in-numbers" },
24
+ title && (react_1.default.createElement("h3", { className: "n-content-heading-3 o3-editorial-typography-subheading cp-in-numbers__title" }, title)),
25
+ react_1.default.createElement("dl", { className: "cp-in-numbers__definitions" }, children))));
26
+ };
27
+ exports.default = InNumbers;
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/content-tree/InNumbers/index.tsx"],"names":[],"mappings":";;;;;;AACA,kDAAyB;AAEzB,uDAAmD;AAInD,MAAM,UAAU,GAAmD,CAAC,EAClE,OAAO,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,GAC/B,EAAE,EAAE;IACH,OAAO,CACL,uCAAK,SAAS,EAAC,2BAA2B;QACxC,sCAAI,SAAS,EAAC,4EAA4E,IACvF,IAAI,CACF;QACL,sCAAI,SAAS,EAAC,4BAA4B,IAAE,WAAW,CAAM,CACzD,CACP,CAAA;AACH,CAAC,CAAA;AA4BQ,gCAAU;AA1BnB;;;;GAIG;AACH,MAAM,SAAS,GAAsD,CAAC,EACpE,OAAO,EACP,QAAQ,GACT,EAAE,EAAE;IACH,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAA;IAEzB,OAAO,CACL,8BAAC,6BAAa,IAAC,UAAU,EAAC,WAAW,EAAC,aAAa,EAAC,eAAe;QACjE,uCAAK,SAAS,EAAC,eAAe,oBAAgB,YAAY;YACvD,KAAK,IAAI,CACR,sCAAI,SAAS,EAAC,6EAA6E,IACxF,KAAK,CACH,CACN;YACD,sCAAI,SAAS,EAAC,4BAA4B,IAAE,QAAQ,CAAM,CACtD,CACQ,CACjB,CAAA;AACH,CAAC,CAAA;AAED,kBAAe,SAAS,CAAA"}
@@ -0,0 +1,18 @@
1
+ import { YouTubePlayer } from 'youtube-player/dist/types';
2
+ interface YTNamespace {
3
+ Player: new (elementId: string | HTMLElement, config?: object) => YouTubePlayer;
4
+ }
5
+ declare global {
6
+ interface Window {
7
+ YT?: YTNamespace;
8
+ onYouTubeIframeAPIReady?: () => void;
9
+ }
10
+ }
11
+ declare class YouTubeClip {
12
+ player: YouTubePlayer | null;
13
+ readonly playerIframe: HTMLElement;
14
+ constructor(iframe: HTMLElement);
15
+ createPlayer(): void;
16
+ static init(): YouTubeClip[];
17
+ }
18
+ export default YouTubeClip;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class YouTubeClip {
4
+ player = null;
5
+ playerIframe;
6
+ constructor(iframe) {
7
+ this.player = null;
8
+ this.playerIframe = iframe;
9
+ }
10
+ createPlayer() {
11
+ const YT = window.YT;
12
+ this.player = new YT.Player(this.playerIframe, {});
13
+ }
14
+ static init() {
15
+ const iframes = document.querySelectorAll('[data-component="youtube-video"] iframe');
16
+ const instances = [];
17
+ iframes.forEach((iframe) => {
18
+ instances.push(new YouTubeClip(iframe));
19
+ });
20
+ if (instances.length > 0) {
21
+ if (window.YT && window.YT.Player) {
22
+ instances.forEach((instance) => instance.createPlayer());
23
+ }
24
+ else {
25
+ window.onYouTubeIframeAPIReady = () => {
26
+ instances.forEach((instance) => instance.createPlayer());
27
+ };
28
+ const script = document.createElement('script');
29
+ script.src = 'https://www.youtube.com/iframe_api';
30
+ document.head.appendChild(script);
31
+ }
32
+ }
33
+ return instances;
34
+ }
35
+ }
36
+ exports.default = YouTubeClip;
37
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/components/content-tree/YoutubeVideo/client/index.ts"],"names":[],"mappings":";;AAgBA,MAAM,WAAW;IACf,MAAM,GAAyB,IAAI,CAAA;IAC1B,YAAY,CAAa;IAElC,YAAY,MAAmB;QAC7B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;QAElB,IAAI,CAAC,YAAY,GAAG,MAAM,CAAA;IAC5B,CAAC;IAED,YAAY;QACV,MAAM,EAAE,GAAG,MAAM,CAAC,EAAiB,CAAA;QAEnC,IAAI,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC,CAAA;IACpD,CAAC;IAED,MAAM,CAAC,IAAI;QACT,MAAM,OAAO,GAAG,QAAQ,CAAC,gBAAgB,CACvC,yCAAyC,CAC1C,CAAA;QACD,MAAM,SAAS,GAAkB,EAAE,CAAA;QAEnC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;YACzB,SAAS,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,MAAqB,CAAC,CAAC,CAAA;QACxD,CAAC,CAAC,CAAA;QAEF,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,IAAI,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC;gBAClC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAA;YAC1D,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,uBAAuB,GAAG,GAAG,EAAE;oBACpC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAA;gBAC1D,CAAC,CAAA;gBACD,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAA;gBAC/C,MAAM,CAAC,GAAG,GAAG,oCAAoC,CAAA;gBACjD,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;YACnC,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAA;IAClB,CAAC;CACF;AAED,kBAAe,WAAW,CAAA"}
@@ -0,0 +1,51 @@
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 client_1 = __importDefault(require("../client"));
7
+ describe('YouTubeClip', () => {
8
+ beforeEach(() => {
9
+ document.body.innerHTML = `
10
+ <div data-component="youtube-video">
11
+ <iframe></iframe>
12
+ </div>
13
+ `;
14
+ delete window.YT;
15
+ delete window.onYouTubeIframeAPIReady;
16
+ document.head.innerHTML = '';
17
+ });
18
+ describe('createPlayer', () => {
19
+ it('should call createPlayer if YT.Player is available', () => {
20
+ const mockPlayer = jest.fn();
21
+ window.YT = { Player: mockPlayer };
22
+ const spyCreatePlayer = jest.spyOn(client_1.default.prototype, 'createPlayer');
23
+ client_1.default.init();
24
+ expect(spyCreatePlayer).toHaveBeenCalled();
25
+ spyCreatePlayer.mockRestore();
26
+ });
27
+ });
28
+ describe('.init', () => {
29
+ it('should create instances of matching iframes', () => {
30
+ const instances = client_1.default.init();
31
+ expect(instances.length).toBe(1);
32
+ });
33
+ it('should set onYouTubeIframeAPIReady add the script if YT.Player is not available', () => {
34
+ const spyCreatePlayer = jest.spyOn(client_1.default.prototype, 'createPlayer');
35
+ const instances = client_1.default.init();
36
+ expect(typeof window.onYouTubeIframeAPIReady).toBe('function');
37
+ const script = document.querySelector('script[src="https://www.youtube.com/iframe_api"]');
38
+ expect(script).not.toBeNull();
39
+ window.YT = { Player: jest.fn() };
40
+ window.onYouTubeIframeAPIReady();
41
+ expect(spyCreatePlayer).toHaveBeenCalledTimes(instances.length);
42
+ spyCreatePlayer.mockRestore();
43
+ });
44
+ it('should return an empty array if there are no matching iframes found', () => {
45
+ document.body.innerHTML = '';
46
+ const instances = client_1.default.init();
47
+ expect(instances.length).toBe(0);
48
+ });
49
+ });
50
+ });
51
+ //# sourceMappingURL=index.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.spec.js","sourceRoot":"","sources":["../../../../../src/components/content-tree/YoutubeVideo/test/index.spec.ts"],"names":[],"mappings":";;;;;AAAA,uDAAmC;AAMnC,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,UAAU,CAAC,GAAG,EAAE;QACd,QAAQ,CAAC,IAAI,CAAC,SAAS,GAAG;;;;KAIzB,CAAA;QAED,OAAQ,MAAiC,CAAC,EAAE,CAAA;QAC5C,OAAQ,MAAiC,CAAC,uBAAuB,CAAA;QACjE,QAAQ,CAAC,IAAI,CAAC,SAAS,GAAG,EAAE,CAAA;IAC9B,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;QAC5B,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;YAC5D,MAAM,UAAU,GAAG,IAAI,CAAC,EAAE,EAAE,CAC3B;YAAC,MAAyC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,CAAA;YACvE,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAW,CAAC,SAAS,EAAE,cAAc,CAAC,CAAA;YACzE,gBAAW,CAAC,IAAI,EAAE,CAAA;YAClB,MAAM,CAAC,eAAe,CAAC,CAAC,gBAAgB,EAAE,CAAA;YAC1C,eAAe,CAAC,WAAW,EAAE,CAAA;QAC/B,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;QACrB,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;YACrD,MAAM,SAAS,GAAG,gBAAW,CAAC,IAAI,EAAE,CAAA;YACpC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAClC,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,iFAAiF,EAAE,GAAG,EAAE;YACzF,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAW,CAAC,SAAS,EAAE,cAAc,CAAC,CAAA;YACzE,MAAM,SAAS,GAAG,gBAAW,CAAC,IAAI,EAAE,CAAA;YAEpC,MAAM,CAAC,OAAO,MAAM,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;YAC9D,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CACnC,kDAAkD,CACnD,CAAA;YACD,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAE5B;YAAC,MAAyC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,CAAA;YACtE,MAAM,CAAC,uBAAwB,EAAE,CAAA;YACjC,MAAM,CAAC,eAAe,CAAC,CAAC,qBAAqB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;YAC/D,eAAe,CAAC,WAAW,EAAE,CAAA;QAC/B,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;YAC7E,QAAQ,CAAC,IAAI,CAAC,SAAS,GAAG,EAAE,CAAA;YAC5B,MAAM,SAAS,GAAG,gBAAW,CAAC,IAAI,EAAE,CAAA;YACpC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAClC,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
package/lib/main.scss CHANGED
@@ -4,4 +4,5 @@
4
4
  @import '../src/components/Topper/client/main.scss';
5
5
  @import '../src/components/content-tree/Clip/client/main.scss';
6
6
  @import '../src/components/content-tree/Flourish/client/main.scss';
7
+ @import '../src/components/content-tree/InNumbers/client/main.scss';
7
8
  @import '../src/components/content-tree/Timeline/client/main.scss';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@financial-times/cp-content-pipeline-ui",
3
- "version": "9.14.1",
3
+ "version": "9.15.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
  "@dotcom-tool-kit/npm": "^5.0.0",
19
- "@financial-times/content-tree": "github:financial-times/content-tree#aa5cf1",
20
- "@financial-times/cp-content-pipeline-client": "^4.21.0",
21
- "@financial-times/cp-content-pipeline-schema": "^3.22.0",
19
+ "@financial-times/content-tree": "github:financial-times/content-tree#746e23",
20
+ "@financial-times/cp-content-pipeline-client": "^4.22.0",
21
+ "@financial-times/cp-content-pipeline-schema": "^3.23.0",
22
22
  "@financial-times/cp-content-pipeline-styles": "^4.6.1",
23
23
  "@financial-times/n-scrollytelling-image": "^1.1.0",
24
24
  "@financial-times/o-grid": "^6.1.8",
@@ -34,11 +34,13 @@
34
34
  "@storybook/react-webpack5": "^7.0.24",
35
35
  "@storybook/testing-library": "^0.2.0",
36
36
  "@sucrase/jest-plugin": "^3.0.0",
37
- "@testing-library/react": "^13.4.0",
37
+ "@testing-library/dom": "^10.4.1",
38
+ "@testing-library/react": "^16.3.1",
38
39
  "@testing-library/user-event": "^14.4.3",
39
40
  "@types/financial-times__n-scrollytelling-image": "0.0.0",
40
41
  "@types/react": "^18.0.15",
41
42
  "@types/react-test-renderer": "^18.3.0",
43
+ "@types/youtube-player": "^5.5.11",
42
44
  "eslint-plugin-react": "^7.30.1",
43
45
  "jest-environment-jsdom": "^29.6.1",
44
46
  "prop-types": "^15.8.1",
@@ -116,13 +116,17 @@ const legacyOverridesToTest = [
116
116
 
117
117
  describe('Body', () => {
118
118
  let mockDate: jest.SpyInstance
119
+ let warnSpy: jest.SpyInstance
119
120
  beforeAll(() => {
120
121
  mockDate = jest
121
122
  .spyOn(Date.prototype, 'toLocaleString')
122
123
  .mockReturnValue('11/06/2024, 14:13:25')
124
+ // suppress warning that LiveBlogPackage is using legacy componentWillReceiveProps in x-interaction component
125
+ warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {})
123
126
  })
124
127
  afterAll(() => {
125
128
  mockDate.mockRestore()
129
+ warnSpy.mockRestore()
126
130
  })
127
131
  describe('default renderers', () => {
128
132
  test.each(typesToTest)('renders default renderer for %s', (type) => {
@@ -63,6 +63,8 @@ describe('<RichText />', () => {
63
63
  })
64
64
 
65
65
  it("ignores components that it doesn't have a mapping for", () => {
66
+ jest.spyOn(console, 'warn').mockImplementation(() => {})
67
+
66
68
  const tree: Body = {
67
69
  type: 'body',
68
70
  version: 1,
@@ -91,6 +93,9 @@ describe('<RichText />', () => {
91
93
  expect(getByText('i should render').tagName).toEqual('P')
92
94
  //wrapping component with react-testing-library is a div
93
95
  expect(getByText('i should not render').tagName).toEqual('DIV')
96
+ expect(console.warn).toHaveBeenCalledWith(
97
+ "couldn't find component for Content Tree node unknown, using fallback component instead (by default will render the node's children)"
98
+ )
94
99
  })
95
100
 
96
101
  it('adds references as props', () => {
@@ -32,6 +32,7 @@ import YoutubeVideo from '../content-tree/YoutubeVideo'
32
32
  import CustomCodeComponent from '../content-tree/CustomCodeComponent'
33
33
  import Timeline from '../content-tree/Timeline'
34
34
  import TimelineEvent from '../content-tree/Timeline/TimelineEvent'
35
+ import InNumbers, { Definition } from '../content-tree/InNumbers'
35
36
 
36
37
  import {
37
38
  List,
@@ -148,6 +149,8 @@ const componentMap: RichTextComponentMapRecord = {
148
149
  'youtube-video': YoutubeVideo,
149
150
  timeline: Timeline,
150
151
  'timeline-event': TimelineEvent,
152
+ 'in-numbers': InNumbers,
153
+ definition: Definition,
151
154
  }
152
155
 
153
156
  function isParentNode(
@@ -0,0 +1,51 @@
1
+ @import "@financial-times/o3-foundation/css/core.css";
2
+ @import "@financial-times/o-grid/main";
3
+
4
+ .cp-in-numbers {
5
+ .cp-in-numbers__title,
6
+ .cp-in-numbers__term,
7
+ .cp-in-numbers__description {
8
+ padding-left: var(--o3-spacing-3xs);
9
+ padding-right: var(--o3-spacing-3xs);
10
+ font-family: var(--o3-type-body-base-font-family);
11
+ }
12
+
13
+ .cp-in-numbers__title.n-content-heading-3 {
14
+ margin-bottom: 2px;
15
+ padding-bottom: var(--o3-spacing-4xs);
16
+ padding-top: var(--o3-spacing-5xs);
17
+ }
18
+
19
+ .cp-in-numbers__definitions {
20
+ margin-top: 0;
21
+ padding-top: var(--o3-spacing-4xs);
22
+ margin-bottom: var(--o3-spacing-3xs);
23
+ display: grid;
24
+ grid-template-columns: repeat(3, 1fr);
25
+
26
+ @include oGridRespondTo($until: M) {
27
+ grid-template-columns: 1fr;
28
+ }
29
+ }
30
+
31
+ .cp-in-numbers__definition {
32
+ margin-top: var(--o3-spacing-5xs);
33
+ margin-bottom: var(--o3-spacing-3xs);
34
+ }
35
+
36
+ .cp-in-numbers__title,
37
+ .cp-in-numbers__definitions {
38
+ background-color: var(--o3-color-palette-wheat-100);
39
+ }
40
+
41
+ .cp-in-numbers__term {
42
+ font-weight: var(--o3-font-weight-semibold);
43
+ }
44
+
45
+ .cp-in-numbers__description {
46
+ margin: var(--o3-spacing-5xs) 0 var(--o3-spacing-3xs);
47
+ font-size: var(--o3-type-body-base-font-size);
48
+ font-weight: var(--o3-type-body-base-font-weight);
49
+ line-height: var(--o3-type-body-base-line-height);
50
+ }
51
+ }
@@ -0,0 +1,47 @@
1
+ import { ContentTree } from '@financial-times/content-tree'
2
+ import React from 'react'
3
+ import { ContentProps } from '../../types'
4
+ import { ContentLayout } from '../../ContentLayout'
5
+
6
+ interface InNumbersProps extends ContentProps<ContentTree.InNumbers> {}
7
+
8
+ const Definition: React.FC<ContentProps<ContentTree.Definition>> = ({
9
+ content: { term, description },
10
+ }) => {
11
+ return (
12
+ <div className="cp-in-numbers__definition">
13
+ <dt className="cp-in-numbers__term n-content-heading-3 o3-editorial-typography-subheading">
14
+ {term}
15
+ </dt>
16
+ <dd className="cp-in-numbers__description">{description}</dd>
17
+ </div>
18
+ )
19
+ }
20
+
21
+ /*
22
+ * @description InNumbers component is used to render a list of numbers with a title.
23
+ * @param content.title - Optional heading for the numbers section.
24
+ * @param children - Rendered Definition components (passed by RichText).
25
+ */
26
+ const InNumbers: React.FC<React.PropsWithChildren<InNumbersProps>> = ({
27
+ content,
28
+ children,
29
+ }) => {
30
+ const { title } = content
31
+
32
+ return (
33
+ <ContentLayout dataLayout="full-grid" dataComponent="cp-in-numbers">
34
+ <div className="cp-in-numbers" data-trackable="in-numbers">
35
+ {title && (
36
+ <h3 className="n-content-heading-3 o3-editorial-typography-subheading cp-in-numbers__title">
37
+ {title}
38
+ </h3>
39
+ )}
40
+ <dl className="cp-in-numbers__definitions">{children}</dl>
41
+ </div>
42
+ </ContentLayout>
43
+ )
44
+ }
45
+
46
+ export default InNumbers
47
+ export { Definition }
@@ -0,0 +1,60 @@
1
+ import { YouTubePlayer } from 'youtube-player/dist/types'
2
+
3
+ interface YTNamespace {
4
+ Player: new (
5
+ elementId: string | HTMLElement,
6
+ config?: object
7
+ ) => YouTubePlayer
8
+ }
9
+
10
+ declare global {
11
+ interface Window {
12
+ YT?: YTNamespace
13
+ onYouTubeIframeAPIReady?: () => void
14
+ }
15
+ }
16
+
17
+ class YouTubeClip {
18
+ player: YouTubePlayer | null = null
19
+ readonly playerIframe: HTMLElement
20
+
21
+ constructor(iframe: HTMLElement) {
22
+ this.player = null
23
+
24
+ this.playerIframe = iframe
25
+ }
26
+
27
+ createPlayer() {
28
+ const YT = window.YT as YTNamespace
29
+
30
+ this.player = new YT.Player(this.playerIframe, {})
31
+ }
32
+
33
+ static init() {
34
+ const iframes = document.querySelectorAll(
35
+ '[data-component="youtube-video"] iframe'
36
+ )
37
+ const instances: YouTubeClip[] = []
38
+
39
+ iframes.forEach((iframe) => {
40
+ instances.push(new YouTubeClip(iframe as HTMLElement))
41
+ })
42
+
43
+ if (instances.length > 0) {
44
+ if (window.YT && window.YT.Player) {
45
+ instances.forEach((instance) => instance.createPlayer())
46
+ } else {
47
+ window.onYouTubeIframeAPIReady = () => {
48
+ instances.forEach((instance) => instance.createPlayer())
49
+ }
50
+ const script = document.createElement('script')
51
+ script.src = 'https://www.youtube.com/iframe_api'
52
+ document.head.appendChild(script)
53
+ }
54
+ }
55
+
56
+ return instances
57
+ }
58
+ }
59
+
60
+ export default YouTubeClip
@@ -0,0 +1,59 @@
1
+ import YouTubeClip from '../client'
2
+
3
+ interface MockYT {
4
+ Player: jest.Mock
5
+ }
6
+
7
+ describe('YouTubeClip', () => {
8
+ beforeEach(() => {
9
+ document.body.innerHTML = `
10
+ <div data-component="youtube-video">
11
+ <iframe></iframe>
12
+ </div>
13
+ `
14
+
15
+ delete (window as Partial<typeof window>).YT
16
+ delete (window as Partial<typeof window>).onYouTubeIframeAPIReady
17
+ document.head.innerHTML = ''
18
+ })
19
+
20
+ describe('createPlayer', () => {
21
+ it('should call createPlayer if YT.Player is available', () => {
22
+ const mockPlayer = jest.fn()
23
+ ;(window as typeof window & { YT: MockYT }).YT = { Player: mockPlayer }
24
+ const spyCreatePlayer = jest.spyOn(YouTubeClip.prototype, 'createPlayer')
25
+ YouTubeClip.init()
26
+ expect(spyCreatePlayer).toHaveBeenCalled()
27
+ spyCreatePlayer.mockRestore()
28
+ })
29
+ })
30
+
31
+ describe('.init', () => {
32
+ it('should create instances of matching iframes', () => {
33
+ const instances = YouTubeClip.init()
34
+ expect(instances.length).toBe(1)
35
+ })
36
+
37
+ it('should set onYouTubeIframeAPIReady add the script if YT.Player is not available', () => {
38
+ const spyCreatePlayer = jest.spyOn(YouTubeClip.prototype, 'createPlayer')
39
+ const instances = YouTubeClip.init()
40
+
41
+ expect(typeof window.onYouTubeIframeAPIReady).toBe('function')
42
+ const script = document.querySelector(
43
+ 'script[src="https://www.youtube.com/iframe_api"]'
44
+ )
45
+ expect(script).not.toBeNull()
46
+
47
+ ;(window as typeof window & { YT: MockYT }).YT = { Player: jest.fn() }
48
+ window.onYouTubeIframeAPIReady!()
49
+ expect(spyCreatePlayer).toHaveBeenCalledTimes(instances.length)
50
+ spyCreatePlayer.mockRestore()
51
+ })
52
+
53
+ it('should return an empty array if there are no matching iframes found', () => {
54
+ document.body.innerHTML = ''
55
+ const instances = YouTubeClip.init()
56
+ expect(instances.length).toBe(0)
57
+ })
58
+ })
59
+ })