@financial-times/cp-content-pipeline-ui 12.4.2 → 12.5.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 (22) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/lib/components/content-tree/Carousel/index.js +4 -7
  3. package/lib/components/content-tree/Carousel/index.js.map +1 -1
  4. package/lib/components/content-tree/Carousel/test/snapshot.spec.js +14 -7
  5. package/lib/components/content-tree/Carousel/test/snapshot.spec.js.map +1 -1
  6. package/lib/main.scss +0 -1
  7. package/package.json +4 -4
  8. package/src/components/content-tree/Carousel/client/main.scss +6 -1
  9. package/src/components/content-tree/Carousel/index.tsx +6 -4
  10. package/src/components/content-tree/Carousel/test/__snapshots__/snapshot.spec.tsx.snap +32 -15
  11. package/src/components/content-tree/Carousel/test/snapshot.spec.tsx +21 -7
  12. package/tsconfig.tsbuildinfo +1 -1
  13. package/lib/components/content-tree/CarouselHeading/index.d.ts +0 -10
  14. package/lib/components/content-tree/CarouselHeading/index.js +0 -16
  15. package/lib/components/content-tree/CarouselHeading/index.js.map +0 -1
  16. package/lib/components/content-tree/CarouselHeading/test/snapshot.spec.d.ts +0 -1
  17. package/lib/components/content-tree/CarouselHeading/test/snapshot.spec.js +0 -26
  18. package/lib/components/content-tree/CarouselHeading/test/snapshot.spec.js.map +0 -1
  19. package/src/components/content-tree/CarouselHeading/client/main.scss +0 -8
  20. package/src/components/content-tree/CarouselHeading/index.tsx +0 -23
  21. package/src/components/content-tree/CarouselHeading/test/__snapshots__/snapshot.spec.tsx.snap +0 -30
  22. package/src/components/content-tree/CarouselHeading/test/snapshot.spec.tsx +0 -32
package/CHANGELOG.md CHANGED
@@ -574,6 +574,21 @@
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
+ ## [12.5.0](https://github.com/Financial-Times/cp-content-pipeline/compare/cp-content-pipeline-ui-v12.4.2...cp-content-pipeline-ui-v12.5.0) (2026-06-25)
578
+
579
+
580
+ ### Features
581
+
582
+ * ci-3707 new content tree model for carousel ([8fbec0a](https://github.com/Financial-Times/cp-content-pipeline/commit/8fbec0a0df8bb296e470ee94bee3c9b652be5ad1))
583
+
584
+
585
+ ### Dependencies
586
+
587
+ * The following workspace dependencies were updated
588
+ * devDependencies
589
+ * @financial-times/cp-content-pipeline-client bumped from ^6.2.0 to ^6.3.0
590
+ * @financial-times/cp-content-pipeline-schema bumped from ^5.3.0 to ^5.4.0
591
+
577
592
  ## [12.4.2](https://github.com/Financial-Times/cp-content-pipeline/compare/cp-content-pipeline-ui-v12.4.1...cp-content-pipeline-ui-v12.4.2) (2026-06-24)
578
593
 
579
594
 
@@ -22,24 +22,21 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
28
25
  Object.defineProperty(exports, "__esModule", { value: true });
29
26
  exports.CarouselCardHeadingLevelContext = void 0;
30
27
  const react_1 = __importStar(require("react"));
31
- const CarouselHeading_1 = __importDefault(require("../CarouselHeading"));
32
28
  /** There may or may not be a main carousel heading. In order to get the heading level correct for the headings in individual carousel cards, we capture what heading levels they should have in context */
33
29
  exports.CarouselCardHeadingLevelContext = (0, react_1.createContext)(3);
34
30
  /**
35
31
  * Renders a Carousel component
36
32
  *
37
33
  */
38
- const Carousel = ({ content: { heading, id }, children, }) => {
39
- const cardHeadingLevel = heading ? 3 : 2;
34
+ const Carousel = ({ content: { title, standfirst, id }, children, }) => {
35
+ const cardHeadingLevel = title ? 3 : 2;
40
36
  return (react_1.default.createElement(exports.CarouselCardHeadingLevelContext.Provider, { value: cardHeadingLevel },
41
37
  react_1.default.createElement("section", { className: "cp-carousel", "data-component": "carousel", "data-component-id": id },
42
- heading && react_1.default.createElement(CarouselHeading_1.default, { content: heading }),
38
+ title && (react_1.default.createElement("h2", { className: "o3-type-title-md cp-carousel__title" }, title)),
39
+ standfirst && react_1.default.createElement("p", { className: "cp-carousel__standfirst" }, standfirst),
43
40
  react_1.default.Children.count(children) > 0 && (react_1.default.createElement("ul", { className: "cp-carousel__cards" }, children)))));
44
41
  };
45
42
  exports.default = Carousel;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/content-tree/Carousel/index.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAA4C;AAK5C,yEAAgD;AAEhD,2MAA2M;AAC9L,QAAA,+BAA+B,GAAG,IAAA,qBAAa,EAAQ,CAAC,CAAC,CAAA;AAGtE;;;GAGG;AAEH,MAAM,QAAQ,GAAqD,CAAC,EAClE,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,EACxB,QAAQ,GACT,EAAE,EAAE;IACH,MAAM,gBAAgB,GAAU,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAC/C,OAAO,CACL,8BAAC,uCAA+B,CAAC,QAAQ,IAAC,KAAK,EAAE,gBAAgB;QAC/D,2CACE,SAAS,EAAC,aAAa,oBACR,UAAU,uBACN,EAAE;YAEpB,OAAO,IAAI,8BAAC,yBAAe,IAAC,OAAO,EAAE,OAAO,GAAI;YAChD,eAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CACrC,sCAAI,SAAS,EAAC,oBAAoB,IAAE,QAAQ,CAAM,CACnD,CACO,CAC+B,CAC5C,CAAA;AACH,CAAC,CAAA;AAED,kBAAe,QAAQ,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/content-tree/Carousel/index.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAA4C;AAM5C,2MAA2M;AAC9L,QAAA,+BAA+B,GAAG,IAAA,qBAAa,EAAQ,CAAC,CAAC,CAAA;AAGtE;;;GAGG;AAEH,MAAM,QAAQ,GAAqD,CAAC,EAClE,OAAO,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,EAClC,QAAQ,GACT,EAAE,EAAE;IACH,MAAM,gBAAgB,GAAU,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAC7C,OAAO,CACL,8BAAC,uCAA+B,CAAC,QAAQ,IAAC,KAAK,EAAE,gBAAgB;QAC/D,2CACE,SAAS,EAAC,aAAa,oBACR,UAAU,uBACN,EAAE;YAEpB,KAAK,IAAI,CACR,sCAAI,SAAS,EAAC,qCAAqC,IAAE,KAAK,CAAM,CACjE;YACA,UAAU,IAAI,qCAAG,SAAS,EAAC,yBAAyB,IAAE,UAAU,CAAK;YACrE,eAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CACrC,sCAAI,SAAS,EAAC,oBAAoB,IAAE,QAAQ,CAAM,CACnD,CACO,CAC+B,CAC5C,CAAA;AACH,CAAC,CAAA;AAED,kBAAe,QAAQ,CAAA"}
@@ -7,7 +7,7 @@ const react_1 = __importDefault(require("react"));
7
7
  const react_2 = require("@testing-library/react");
8
8
  const index_1 = __importDefault(require("../index"));
9
9
  describe('Carousel', () => {
10
- it('renders without a heading', () => {
10
+ it('renders without a title or standfirst', () => {
11
11
  const { container } = (0, react_2.render)(react_1.default.createElement(index_1.default, { content: {
12
12
  id: 'carousel-1',
13
13
  type: 'carousel',
@@ -16,15 +16,22 @@ describe('Carousel', () => {
16
16
  react_1.default.createElement("li", null, "Carousel card")));
17
17
  expect(container.firstChild).toMatchSnapshot();
18
18
  });
19
- it('renders with a heading', () => {
19
+ it('renders with a title but no standfirst', () => {
20
20
  const { container } = (0, react_2.render)(react_1.default.createElement(index_1.default, { content: {
21
21
  id: 'carousel-1',
22
22
  type: 'carousel',
23
- heading: {
24
- type: 'carousel-heading',
25
- title: 'Inside Business',
26
- standfirst: 'Analysis and insight from FT specialists',
27
- },
23
+ title: 'Inside Business',
24
+ children: [],
25
+ } },
26
+ react_1.default.createElement("li", null, "Carousel card")));
27
+ expect(container.firstChild).toMatchSnapshot();
28
+ });
29
+ it('renders with a title and standfirst', () => {
30
+ const { container } = (0, react_2.render)(react_1.default.createElement(index_1.default, { content: {
31
+ id: 'carousel-1',
32
+ type: 'carousel',
33
+ title: 'Inside Business',
34
+ standfirst: 'Analysis and insight from FT specialists',
28
35
  children: [],
29
36
  } },
30
37
  react_1.default.createElement("li", null, "Carousel card")));
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot.spec.js","sourceRoot":"","sources":["../../../../../src/components/content-tree/Carousel/test/snapshot.spec.tsx"],"names":[],"mappings":";;;;;AAAA,kDAAyB;AACzB,kDAA+C;AAC/C,qDAA+B;AAE/B,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;IACxB,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,EAAE,SAAS,EAAE,GAAG,IAAA,cAAM,EAC1B,8BAAC,eAAQ,IACP,OAAO,EAAE;gBACP,EAAE,EAAE,YAAY;gBAChB,IAAI,EAAE,UAAU;gBAChB,QAAQ,EAAE,EAAE;aACb;YAED,0DAAsB,CACb,CACZ,CAAA;QAED,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,eAAe,EAAE,CAAA;IAChD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,MAAM,EAAE,SAAS,EAAE,GAAG,IAAA,cAAM,EAC1B,8BAAC,eAAQ,IACP,OAAO,EAAE;gBACP,EAAE,EAAE,YAAY;gBAChB,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE;oBACP,IAAI,EAAE,kBAAkB;oBACxB,KAAK,EAAE,iBAAiB;oBACxB,UAAU,EAAE,0CAA0C;iBACvD;gBACD,QAAQ,EAAE,EAAE;aACb;YAED,0DAAsB,CACb,CACZ,CAAA;QAED,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,eAAe,EAAE,CAAA;IAChD,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"snapshot.spec.js","sourceRoot":"","sources":["../../../../../src/components/content-tree/Carousel/test/snapshot.spec.tsx"],"names":[],"mappings":";;;;;AAAA,kDAAyB;AACzB,kDAA+C;AAC/C,qDAA+B;AAE/B,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;IACxB,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,EAAE,SAAS,EAAE,GAAG,IAAA,cAAM,EAC1B,8BAAC,eAAQ,IACP,OAAO,EAAE;gBACP,EAAE,EAAE,YAAY;gBAChB,IAAI,EAAE,UAAU;gBAChB,QAAQ,EAAE,EAAE;aACb;YAED,0DAAsB,CACb,CACZ,CAAA;QAED,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,eAAe,EAAE,CAAA;IAChD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,EAAE,SAAS,EAAE,GAAG,IAAA,cAAM,EAC1B,8BAAC,eAAQ,IACP,OAAO,EAAE;gBACP,EAAE,EAAE,YAAY;gBAChB,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE,iBAAiB;gBACxB,QAAQ,EAAE,EAAE;aACb;YAED,0DAAsB,CACb,CACZ,CAAA;QAED,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,eAAe,EAAE,CAAA;IAChD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,EAAE,SAAS,EAAE,GAAG,IAAA,cAAM,EAC1B,8BAAC,eAAQ,IACP,OAAO,EAAE;gBACP,EAAE,EAAE,YAAY;gBAChB,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE,iBAAiB;gBACxB,UAAU,EAAE,0CAA0C;gBACtD,QAAQ,EAAE,EAAE;aACb;YAED,0DAAsB,CACb,CACZ,CAAA;QAED,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,eAAe,EAAE,CAAA;IAChD,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
package/lib/main.scss CHANGED
@@ -6,7 +6,6 @@
6
6
  @import '../src/components/content-tree/Card/client/main.scss';
7
7
  @import '../src/components/content-tree/Carousel/client/main.scss';
8
8
  @import '../src/components/content-tree/CarouselCard/client/main.scss';
9
- @import '../src/components/content-tree/CarouselHeading/client/main.scss';
10
9
  @import '../src/components/content-tree/Clip/client/main.scss';
11
10
  @import '../src/components/content-tree/Flourish/client/main.scss';
12
11
  @import '../src/components/content-tree/ImagePair/client/main.scss';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@financial-times/cp-content-pipeline-ui",
3
- "version": "12.4.2",
3
+ "version": "12.5.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.1",
19
- "@financial-times/content-tree": "^0.12.0",
20
- "@financial-times/cp-content-pipeline-client": "^6.2.0",
21
- "@financial-times/cp-content-pipeline-schema": "^5.3.0",
19
+ "@financial-times/content-tree": "^0.14.0",
20
+ "@financial-times/cp-content-pipeline-client": "^6.3.0",
21
+ "@financial-times/cp-content-pipeline-schema": "^5.4.0",
22
22
  "@financial-times/cp-content-pipeline-styles": "^4.8.2",
23
23
  "@financial-times/n-scrollytelling-image": "^1.1.0",
24
24
  "@financial-times/o-grid": "^6.1.8",
@@ -1,8 +1,13 @@
1
1
  $carousel-gap: var(--o3-spacing-2xs);
2
2
  $carousel-gap--wide: var(--o3-spacing-s);
3
3
  @import '../../CarouselCard/client/main.scss';
4
- @import '../../CarouselHeading/client/main.scss';
5
4
  .cp-carousel {
5
+ .cp-carousel__title {
6
+ margin: 0 0 var(--o3-spacing-2xs);
7
+ }
8
+ .cp-carousel__standfirst {
9
+ margin: 0 0 var(--o3-spacing-s);
10
+ }
6
11
  .cp-carousel__cards {
7
12
  padding: 0;
8
13
  margin: 0 0 var(--o3-spacing-xs);
@@ -3,7 +3,6 @@ import React, { createContext } from 'react'
3
3
  import { ContentTree } from '@financial-times/content-tree'
4
4
 
5
5
  import { ContentProps } from '../../types'
6
- import CarouselHeading from '../CarouselHeading'
7
6
 
8
7
  /** There may or may not be a main carousel heading. In order to get the heading level correct for the headings in individual carousel cards, we capture what heading levels they should have in context */
9
8
  export const CarouselCardHeadingLevelContext = createContext<2 | 3>(3)
@@ -15,10 +14,10 @@ interface CarouselProps extends ContentProps<ContentTree.transit.Carousel> {}
15
14
  */
16
15
 
17
16
  const Carousel: React.FC<React.PropsWithChildren<CarouselProps>> = ({
18
- content: { heading, id },
17
+ content: { title, standfirst, id },
19
18
  children,
20
19
  }) => {
21
- const cardHeadingLevel: 2 | 3 = heading ? 3 : 2
20
+ const cardHeadingLevel: 2 | 3 = title ? 3 : 2
22
21
  return (
23
22
  <CarouselCardHeadingLevelContext.Provider value={cardHeadingLevel}>
24
23
  <section
@@ -26,7 +25,10 @@ const Carousel: React.FC<React.PropsWithChildren<CarouselProps>> = ({
26
25
  data-component="carousel"
27
26
  data-component-id={id}
28
27
  >
29
- {heading && <CarouselHeading content={heading} />}
28
+ {title && (
29
+ <h2 className="o3-type-title-md cp-carousel__title">{title}</h2>
30
+ )}
31
+ {standfirst && <p className="cp-carousel__standfirst">{standfirst}</p>}
30
32
  {React.Children.count(children) > 0 && (
31
33
  <ul className="cp-carousel__cards">{children}</ul>
32
34
  )}
@@ -1,25 +1,42 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`Carousel renders with a heading 1`] = `
3
+ exports[`Carousel renders with a title and standfirst 1`] = `
4
4
  <section
5
5
  class="cp-carousel"
6
6
  data-component="carousel"
7
7
  data-component-id="carousel-1"
8
8
  >
9
- <div
10
- class="cp-carousel__heading"
9
+ <h2
10
+ class="o3-type-title-md cp-carousel__title"
11
11
  >
12
- <h2
13
- class="o3-type-title-md cp-carousel__heading__title"
14
- >
15
- Inside Business
16
- </h2>
17
- <p
18
- class="cp-carousel__heading__standfirst"
19
- >
20
- Analysis and insight from FT specialists
21
- </p>
22
- </div>
12
+ Inside Business
13
+ </h2>
14
+ <p
15
+ class="cp-carousel__standfirst"
16
+ >
17
+ Analysis and insight from FT specialists
18
+ </p>
19
+ <ul
20
+ class="cp-carousel__cards"
21
+ >
22
+ <li>
23
+ Carousel card
24
+ </li>
25
+ </ul>
26
+ </section>
27
+ `;
28
+
29
+ exports[`Carousel renders with a title but no standfirst 1`] = `
30
+ <section
31
+ class="cp-carousel"
32
+ data-component="carousel"
33
+ data-component-id="carousel-1"
34
+ >
35
+ <h2
36
+ class="o3-type-title-md cp-carousel__title"
37
+ >
38
+ Inside Business
39
+ </h2>
23
40
  <ul
24
41
  class="cp-carousel__cards"
25
42
  >
@@ -30,7 +47,7 @@ exports[`Carousel renders with a heading 1`] = `
30
47
  </section>
31
48
  `;
32
49
 
33
- exports[`Carousel renders without a heading 1`] = `
50
+ exports[`Carousel renders without a title or standfirst 1`] = `
34
51
  <section
35
52
  class="cp-carousel"
36
53
  data-component="carousel"
@@ -3,7 +3,7 @@ import { render } from '@testing-library/react'
3
3
  import Carousel from '../index'
4
4
 
5
5
  describe('Carousel', () => {
6
- it('renders without a heading', () => {
6
+ it('renders without a title or standfirst', () => {
7
7
  const { container } = render(
8
8
  <Carousel
9
9
  content={{
@@ -19,17 +19,31 @@ describe('Carousel', () => {
19
19
  expect(container.firstChild).toMatchSnapshot()
20
20
  })
21
21
 
22
- it('renders with a heading', () => {
22
+ it('renders with a title but no standfirst', () => {
23
23
  const { container } = render(
24
24
  <Carousel
25
25
  content={{
26
26
  id: 'carousel-1',
27
27
  type: 'carousel',
28
- heading: {
29
- type: 'carousel-heading',
30
- title: 'Inside Business',
31
- standfirst: 'Analysis and insight from FT specialists',
32
- },
28
+ title: 'Inside Business',
29
+ children: [],
30
+ }}
31
+ >
32
+ <li>Carousel card</li>
33
+ </Carousel>
34
+ )
35
+
36
+ expect(container.firstChild).toMatchSnapshot()
37
+ })
38
+
39
+ it('renders with a title and standfirst', () => {
40
+ const { container } = render(
41
+ <Carousel
42
+ content={{
43
+ id: 'carousel-1',
44
+ type: 'carousel',
45
+ title: 'Inside Business',
46
+ standfirst: 'Analysis and insight from FT specialists',
33
47
  children: [],
34
48
  }}
35
49
  >