@financial-times/cp-content-pipeline-ui 3.0.1 → 3.0.2

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 CHANGED
@@ -363,6 +363,13 @@
363
363
  * @financial-times/cp-content-pipeline-client bumped from ^1.3.11 to ^1.3.12
364
364
  * @financial-times/cp-content-pipeline-schema bumped from ^1.3.8 to ^1.3.9
365
365
 
366
+ ## [3.0.2](https://github.com/Financial-Times/cp-content-pipeline/compare/cp-content-pipeline-ui-v3.0.1...cp-content-pipeline-ui-v3.0.2) (2023-09-28)
367
+
368
+
369
+ ### Documentation
370
+
371
+ * update ui readme to trigger release ([2b12d81](https://github.com/Financial-Times/cp-content-pipeline/commit/2b12d810ccac9eca67bd7242a447ae1f18f9f78f))
372
+
366
373
  ## [3.0.1](https://github.com/Financial-Times/cp-content-pipeline/compare/cp-content-pipeline-ui-v3.0.0...cp-content-pipeline-ui-v3.0.1) (2023-09-28)
367
374
 
368
375
 
package/README.md CHANGED
@@ -47,6 +47,7 @@ const componentOverrides = {
47
47
  Each Component in this package contains a function which returns a JSX object. Components can be combined to form content views which can be rendered on ft.com, the apps or the edit. Components may be nested, for example the `<Body>` pulls in other components to form a complete article Body.
48
48
 
49
49
  ## Storybook
50
+
50
51
  You can visually test the ui components on Storyboook running the following command:
51
52
 
52
53
  ```
@@ -90,7 +91,7 @@ Our [Schema](../schema/README.md) package uses converts a `bodyXML` from the con
90
91
 
91
92
  ### What is a Content Tree?
92
93
 
93
- [Content Tree] is a format for representing Financial Times article content as a JSON tree (following the [unist](https://github.com/syntax-tree/unist) spec).
94
+ [Content Tree](https://github.com/Financial-Times/content-tree) is a format for representing Financial Times article content as a JSON tree (following the [unist](https://github.com/syntax-tree/unist) spec).
94
95
 
95
96
  It is a shared contract between [Spark](https://biz-ops.in.ft.com/Team/digitalnewsroomsupport) and [Customer Products](https://biz-ops.in.ft.com/Group/customerproducts) defining what the content should look like, so that it can be used to both preview and render an article.
96
97
 
@@ -1,6 +1,6 @@
1
1
  import { ContentTree } from '@financial-times/content-tree';
2
2
  import React from 'react';
3
3
  export declare const ParagraphContext: React.Context<{
4
- className?: string | undefined;
5
- } | undefined>;
4
+ className: string;
5
+ } | null>;
6
6
  export default function Paragraph(props: React.PropsWithChildren<ContentTree.Paragraph>): React.JSX.Element;
@@ -25,9 +25,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.ParagraphContext = void 0;
27
27
  const react_1 = __importStar(require("react"));
28
- exports.ParagraphContext = (0, react_1.createContext)(undefined);
28
+ exports.ParagraphContext = (0, react_1.createContext)(null);
29
29
  function Paragraph(props) {
30
- return (react_1.default.createElement(exports.ParagraphContext.Consumer, null, ({ className } = { className: undefined }) => (react_1.default.createElement("p", { ...{ className } }, props.children))));
30
+ const { className } = (0, react_1.useContext)(exports.ParagraphContext) ?? { className: undefined };
31
+ return react_1.default.createElement("p", { ...{ className } }, props.children);
31
32
  }
32
33
  exports.default = Paragraph;
33
34
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/Paragraph/index.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AACA,+CAA4C;AAE/B,QAAA,gBAAgB,GAAG,IAAA,qBAAa,EAE3C,SAAS,CAAC,CAAA;AAEZ,SAAwB,SAAS,CAC/B,KAAqD;IAErD,OAAO,CACL,8BAAC,wBAAgB,CAAC,QAAQ,QACvB,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAC7C,wCAAO,EAAE,SAAS,EAAE,IAAG,KAAK,CAAC,QAAQ,CAAK,CAC3C,CACyB,CAC7B,CAAA;AACH,CAAC;AAVD,4BAUC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/Paragraph/index.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AACA,+CAAwD;AAE3C,QAAA,gBAAgB,GAAG,IAAA,qBAAa,EAC3C,IAAI,CACL,CAAA;AAED,SAAwB,SAAS,CAC/B,KAAqD;IAErD,MAAM,EAAE,SAAS,EAAE,GAAG,IAAA,kBAAU,EAAC,wBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,CAAA;IAE9E,OAAO,wCAAO,EAAE,SAAS,EAAE,IAAG,KAAK,CAAC,QAAQ,CAAK,CAAA;AACnD,CAAC;AAND,4BAMC"}
@@ -1,10 +1,30 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
4
24
  };
5
25
  Object.defineProperty(exports, "__esModule", { value: true });
6
26
  exports.ScrollyImage = void 0;
7
- const react_1 = __importDefault(require("react"));
27
+ const react_1 = __importStar(require("react"));
8
28
  const ImageSet_1 = require("../ImageSet");
9
29
  const _1 = require(".");
10
30
  const scrollyGetBreakpoints = (image) => {
@@ -26,16 +46,17 @@ const scrollyGetBreakpoints = (image) => {
26
46
  }
27
47
  };
28
48
  function ScrollyImage({ picture, }) {
49
+ const scrollyId = (0, react_1.useContext)(_1.ScrollyIDContext);
29
50
  if (!picture?.images) {
30
51
  throw new Error(`ScrollyImage has no images. Check that they are present in the query`);
31
52
  }
32
- return (react_1.default.createElement(_1.ScrollyIDContext.Consumer, null, (scrollyId) => (react_1.default.createElement("figure", { className: "n-scrollytelling__figure n-content-image--full", "data-scrollytelling-slide": scrollyId },
53
+ return (react_1.default.createElement("figure", { className: "n-scrollytelling__figure n-content-image--full", "data-scrollytelling-slide": scrollyId },
33
54
  react_1.default.createElement("picture", null,
34
55
  react_1.default.createElement(ImageSet_1.Sources, { images: picture.images, getBreakpoints: scrollyGetBreakpoints }),
35
56
  react_1.default.createElement(ImageSet_1.FallbackImage, { image: picture.fallbackImage, imageType: picture.imageType, className: "n-scrollytelling__image" })),
36
57
  (picture.caption || picture.credit) && (react_1.default.createElement("figcaption", { className: "n-scrollytelling__caption n-scrollytelling__caption--has-caption" },
37
58
  picture.caption ? picture.caption + ' ' : '',
38
- picture.credit ? `© ${picture.credit}` : ''))))));
59
+ picture.credit ? `© ${picture.credit}` : ''))));
39
60
  }
40
61
  exports.ScrollyImage = ScrollyImage;
41
62
  //# sourceMappingURL=ScrollyImage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ScrollyImage.js","sourceRoot":"","sources":["../../../src/components/Scrollytelling/ScrollyImage.tsx"],"names":[],"mappings":";;;;;;AAEA,kDAAyB;AACzB,0CAAsE;AACtE,wBAAoC;AAEpC,MAAM,qBAAqB,GAAqB,CAAC,KAAK,EAAE,EAAE;IACxD,QAAQ,KAAK,CAAC,MAAM,EAAE;QACpB,KAAK,SAAS;YACZ,OAAO;gBACL,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE;gBAC9C,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE;gBAC9C,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE;gBAC/C,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE;aACjD,CAAA;QACH,KAAK,QAAQ;YACX,OAAO;gBACL,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,UAAU,EAAE;gBAC7C,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,UAAU,EAAE;gBAC7C,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,UAAU,EAAE;gBAC7C,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE;aAChD,CAAA;KACJ;AACH,CAAC,CAAA;AAED,SAAgB,YAAY,CAAC,EAC3B,OAAO,GACyC;IAChD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE;QACpB,MAAM,IAAI,KAAK,CACb,sEAAsE,CACvE,CAAA;KACF;IAED,OAAO,CACL,8BAAC,mBAAgB,CAAC,QAAQ,QACvB,CAAC,SAAS,EAAE,EAAE,CAAC,CACd,0CACE,SAAS,EAAC,gDAAgD,+BAC/B,SAAS;QAEpC;YACE,8BAAC,kBAAO,IACN,MAAM,EAAE,OAAO,CAAC,MAAM,EACtB,cAAc,EAAE,qBAAqB,GACrC;YACF,8BAAC,wBAAa,IACZ,KAAK,EAAE,OAAO,CAAC,aAAa,EAC5B,SAAS,EAAE,OAAO,CAAC,SAAS,EAC5B,SAAS,EAAC,yBAAyB,GACnC,CACM;QACT,CAAC,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,CACtC,8CAAY,SAAS,EAAC,kEAAkE;YACrF,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE;YAC5C,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CACjC,CACd,CACM,CACV,CACyB,CAC7B,CAAA;AACH,CAAC;AArCD,oCAqCC"}
1
+ {"version":3,"file":"ScrollyImage.js","sourceRoot":"","sources":["../../../src/components/Scrollytelling/ScrollyImage.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,+CAAyC;AACzC,0CAAsE;AACtE,wBAAoC;AAEpC,MAAM,qBAAqB,GAAqB,CAAC,KAAK,EAAE,EAAE;IACxD,QAAQ,KAAK,CAAC,MAAM,EAAE;QACpB,KAAK,SAAS;YACZ,OAAO;gBACL,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE;gBAC9C,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE;gBAC9C,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE;gBAC/C,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE;aACjD,CAAA;QACH,KAAK,QAAQ;YACX,OAAO;gBACL,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,UAAU,EAAE;gBAC7C,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,UAAU,EAAE;gBAC7C,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,UAAU,EAAE;gBAC7C,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE;aAChD,CAAA;KACJ;AACH,CAAC,CAAA;AAED,SAAgB,YAAY,CAAC,EAC3B,OAAO,GACyC;IAChD,MAAM,SAAS,GAAG,IAAA,kBAAU,EAAC,mBAAgB,CAAC,CAAA;IAE9C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE;QACpB,MAAM,IAAI,KAAK,CACb,sEAAsE,CACvE,CAAA;KACF;IAED,OAAO,CACL,0CACE,SAAS,EAAC,gDAAgD,+BAC/B,SAAS;QAEpC;YACE,8BAAC,kBAAO,IACN,MAAM,EAAE,OAAO,CAAC,MAAM,EACtB,cAAc,EAAE,qBAAqB,GACrC;YACF,8BAAC,wBAAa,IACZ,KAAK,EAAE,OAAO,CAAC,aAAa,EAC5B,SAAS,EAAE,OAAO,CAAC,SAAS,EAC5B,SAAS,EAAC,yBAAyB,GACnC,CACM;QACT,CAAC,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,CACtC,8CAAY,SAAS,EAAC,kEAAkE;YACrF,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE;YAC5C,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CACjC,CACd,CACM,CACV,CAAA;AACH,CAAC;AAnCD,oCAmCC"}
@@ -1,6 +1,6 @@
1
1
  import React, { FC, PropsWithChildren } from 'react';
2
2
  import type { ContentTree } from '@financial-times/content-tree';
3
- export declare const ScrollyIDContext: React.Context<string | undefined>;
3
+ export declare const ScrollyIDContext: React.Context<string | null>;
4
4
  export declare const ScrollyBlock: FC<PropsWithChildren<Omit<ContentTree.ScrollyBlock, 'children'>> & {
5
5
  parentIndex: number;
6
6
  }>;
@@ -30,22 +30,22 @@ exports.ScrollyHeading = exports.ScrollyCopy = exports.ScrollySection = exports.
30
30
  const react_1 = __importStar(require("react"));
31
31
  const classnames_1 = __importDefault(require("classnames"));
32
32
  const Paragraph_1 = require("../Paragraph");
33
- exports.ScrollyIDContext = (0, react_1.createContext)(undefined);
33
+ exports.ScrollyIDContext = (0, react_1.createContext)(null);
34
34
  const ScrollyBlock = ({ children, theme, parentIndex }) => (react_1.default.createElement("div", { className: "n-content-layout n-content-layout--scrollytelling", "data-layout-name": "auto" },
35
35
  react_1.default.createElement("div", { className: (0, classnames_1.default)('n-scrollytelling', `n-scrollytelling--theme-${theme}`), "data-component": "scrollytelling-image", "data-scrollytelling-theme": theme },
36
36
  react_1.default.createElement("div", { className: "n-scrollytelling__viewport" }, react_1.default.Children.map(children, (child, index) => (react_1.default.createElement(exports.ScrollyIDContext.Provider, { value: `${parentIndex}-${index}` }, child)))))));
37
37
  exports.ScrollyBlock = ScrollyBlock;
38
- const ScrollySectionOptionsContext = (0, react_1.createContext)(undefined);
38
+ const ScrollySectionOptionsContext = (0, react_1.createContext)(null);
39
39
  const ScrollySection = ({ children, display, noBox, position, transition }) => (react_1.default.createElement(ScrollySectionOptionsContext.Provider, { value: { display, noBox, position, transition } },
40
40
  react_1.default.createElement(react_1.default.Fragment, null, children)));
41
41
  exports.ScrollySection = ScrollySection;
42
- const ScrollyCopy = ({ children, }) => (react_1.default.createElement(exports.ScrollyIDContext.Consumer, null, (scrollyId) => (react_1.default.createElement(ScrollySectionOptionsContext.Consumer, null, ({ display, noBox, position, transition } = {
43
- display: 'dark-background',
44
- position: 'center',
45
- }) => {
46
- const displaySuffix = display === 'dark-background'
47
- ? 'background-dark'
48
- : 'background-light';
42
+ const ScrollyCopy = ({ children, }) => {
43
+ const { display, noBox, position, transition } = (0, react_1.useContext)(ScrollySectionOptionsContext) ?? {
44
+ display: 'dark-background',
45
+ position: 'center',
46
+ };
47
+ const scrollyId = (0, react_1.useContext)(exports.ScrollyIDContext);
48
+ const displaySuffix = display === 'dark-background' ? 'background-dark' : 'background-light';
49
49
  return (react_1.default.createElement("div", { className: (0, classnames_1.default)('n-scrollytelling__overlay-text-slide', `n-scrollytelling__overlay-text-slide--position-${position}`, {
50
50
  'n-scrollytelling__overlay-text-slide-box--transparent': noBox,
51
51
  [`n-scrollytelling__overlay-text-slide-box--${displaySuffix}`]: display,
@@ -57,7 +57,7 @@ const ScrollyCopy = ({ children, }) => (react_1.default.createElement(exports.Sc
57
57
  }) },
58
58
  react_1.default.createElement(Paragraph_1.ParagraphContext.Provider, { value: { className: 'n-scrollytelling__overlay-text' } },
59
59
  react_1.default.createElement(react_1.default.Fragment, null, children)))));
60
- }))));
60
+ };
61
61
  exports.ScrollyCopy = ScrollyCopy;
62
62
  const ScrollyHeading = ({ children, level }) => {
63
63
  const classNames = (0, classnames_1.default)('n-scrollytelling__overlay-text', `n-scrollytelling__overlay-text--text-style-${level}`);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/Scrollytelling/index.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAmE;AAEnE,4DAAmC;AAEnC,4CAA+C;AAElC,QAAA,gBAAgB,GAAG,IAAA,qBAAa,EAAqB,SAAS,CAAC,CAAA;AAErE,MAAM,YAAY,GAIrB,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CACxC,uCACE,SAAS,EAAC,mDAAmD,sBAC5C,MAAM;IAEvB,uCACE,SAAS,EAAE,IAAA,oBAAU,EACnB,kBAAkB,EAClB,2BAA2B,KAAK,EAAE,CACnC,oBACc,sBAAsB,+BACV,KAAK;QAEhC,uCAAK,SAAS,EAAC,4BAA4B,IACxC,eAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAC9C,8BAAC,wBAAgB,CAAC,QAAQ,IAAC,KAAK,EAAE,GAAG,WAAW,IAAI,KAAK,EAAE,IACxD,KAAK,CACoB,CAC7B,CAAC,CACE,CACF,CACF,CACP,CAAA;AA1BY,QAAA,YAAY,gBA0BxB;AAOD,MAAM,4BAA4B,GAAG,IAAA,qBAAa,EAEhD,SAAS,CAAC,CAAA;AAEL,MAAM,cAAc,GAEvB,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAC1D,8BAAC,4BAA4B,CAAC,QAAQ,IACpC,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE;IAE/C,8DAAG,QAAQ,CAAI,CACuB,CACzC,CAAA;AARY,QAAA,cAAc,kBAQ1B;AAKM,MAAM,WAAW,GAAmD,CAAC,EAC1E,QAAQ,GACT,EAAE,EAAE,CAAC,CACJ,8BAAC,wBAAgB,CAAC,QAAQ,QACvB,CAAC,SAAS,EAAE,EAAE,CAAC,CACd,8BAAC,4BAA4B,CAAC,QAAQ,QACnC,CACC,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG;IACzC,OAAO,EAAE,iBAAiB;IAC1B,QAAQ,EAAE,QAAQ;CACnB,EACD,EAAE;IACF,MAAM,aAAa,GACjB,OAAO,KAAK,iBAAiB;QAC3B,CAAC,CAAC,iBAAiB;QACnB,CAAC,CAAC,kBAAkB,CAAA;IACxB,OAAO,CACL,uCACE,SAAS,EAAE,IAAA,oBAAU,EACnB,sCAAsC,EACtC,kDAAkD,QAAQ,EAAE,EAC5D;YACE,uDAAuD,EACrD,KAAK;YACP,CAAC,6CAA6C,aAAa,EAAE,CAAC,EAC5D,OAAO;YACT,CAAC,yCAAyC,UAAU,EAAE,CAAC,EACrD,UAAU;SACb,CACF,oCAC+B,SAAS;QAEzC,uCACE,SAAS,EAAE,IAAA,oBAAU,EAAC,oCAAoC,EAAE;gBAC1D,iDAAiD,EAAE,KAAK;gBACxD,CAAC,uCAAuC,aAAa,EAAE,CAAC,EACtD,OAAO;aACV,CAAC;YAEF,8BAAC,4BAAgB,CAAC,QAAQ,IACxB,KAAK,EAAE,EAAE,SAAS,EAAE,gCAAgC,EAAE;gBAEtD,8DAAG,QAAQ,CAAI,CACW,CACxB,CACF,CACP,CAAA;AACH,CAAC,CACqC,CACzC,CACyB,CAC7B,CAAA;AAnDY,QAAA,WAAW,eAmDvB;AAEM,MAAM,cAAc,GAEvB,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE;IAC1B,MAAM,UAAU,GAAG,IAAA,oBAAU,EAC3B,gCAAgC,EAChC,8CAA8C,KAAK,EAAE,CACtD,CAAA;IAED,QAAQ,KAAK,EAAE;QACb,KAAK,SAAS;YACZ,OAAO,sCAAI,SAAS,EAAE,UAAU;;gBAAI,QAAQ;oBAAO,CAAA;QACrD,KAAK,SAAS;YACZ,OAAO,sCAAI,SAAS,EAAE,UAAU;;gBAAI,QAAQ;oBAAO,CAAA;QACrD,KAAK,YAAY;YACf,OAAO,sCAAI,SAAS,EAAE,UAAU;;gBAAI,QAAQ;oBAAO,CAAA;KACtD;AACH,CAAC,CAAA;AAhBY,QAAA,cAAc,kBAgB1B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/Scrollytelling/index.tsx"],"names":[],"mappings":"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"}
@@ -1,13 +1,37 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
27
  };
5
28
  Object.defineProperty(exports, "__esModule", { value: true });
6
29
  exports.TableCell = void 0;
7
- const react_1 = __importDefault(require("react"));
30
+ const react_1 = __importStar(require("react"));
8
31
  const _1 = require(".");
9
32
  const classnames_1 = __importDefault(require("classnames"));
10
- const TableCell = (props) => (react_1.default.createElement(_1.ColumnSettingsContext.Consumer, null, (allColumnSettings) => {
33
+ const TableCell = (props) => {
34
+ const allColumnSettings = (0, react_1.useContext)(_1.ColumnSettingsContext);
11
35
  const columnSettings = allColumnSettings[props.parentIndex] ?? {
12
36
  hideOnMobile: false,
13
37
  sortable: false,
@@ -18,6 +42,6 @@ const TableCell = (props) => (react_1.default.createElement(_1.ColumnSettingsCon
18
42
  'o-table__cell--numeric': columnSettings.sortType === 'number',
19
43
  'n-content-body__table-cell--hide-mobile': columnSettings.hideOnMobile,
20
44
  }) }, props.children));
21
- }));
45
+ };
22
46
  exports.TableCell = TableCell;
23
47
  //# sourceMappingURL=TableCell.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TableCell.js","sourceRoot":"","sources":["../../../src/components/Table/TableCell.tsx"],"names":[],"mappings":";;;;;;AAAA,kDAAyB;AAEzB,wBAAyC;AAEzC,4DAAmC;AAE5B,MAAM,SAAS,GAAG,CACvB,KAEC,EACD,EAAE,CAAC,CACH,8BAAC,wBAAqB,CAAC,QAAQ,QAC5B,CAAC,iBAAiB,EAAE,EAAE;IACrB,MAAM,cAAc,GAAwB,iBAAiB,CAC3D,KAAK,CAAC,WAAW,CAClB,IAAI;QACH,YAAY,EAAE,KAAK;QACnB,QAAQ,EAAE,KAAK;KAChB,CAAA;IAED,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CACrB,sCACE,SAAS,EAAE,IAAA,oBAAU,EAAC;YACpB,yCAAyC,EACvC,cAAc,CAAC,YAAY;SAC9B,CAAC,0BACoB,cAAc,CAAC,QAAQ,4BACrB,cAAc,CAAC,QAAQ,EAC/C,KAAK,EAAC,KAAK,EACX,IAAI,EAAC,cAAc,IAElB,KAAK,CAAC,QAAQ,CACZ,CACN,CAAC,CAAC,CAAC,CACF,sCACE,SAAS,EAAE,IAAA,oBAAU,EAAC;YACpB,wBAAwB,EAAE,cAAc,CAAC,QAAQ,KAAK,QAAQ;YAC9D,yCAAyC,EACvC,cAAc,CAAC,YAAY;SAC9B,CAAC,IAED,KAAK,CAAC,QAAQ,CACZ,CACN,CAAA;AACH,CAAC,CAC8B,CAClC,CAAA;AAxCY,QAAA,SAAS,aAwCrB"}
1
+ {"version":3,"file":"TableCell.js","sourceRoot":"","sources":["../../../src/components/Table/TableCell.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAyC;AAEzC,wBAAyC;AAEzC,4DAAmC;AAE5B,MAAM,SAAS,GAAG,CACvB,KAEC,EACD,EAAE;IACF,MAAM,iBAAiB,GAAG,IAAA,kBAAU,EAAC,wBAAqB,CAAC,CAAA;IAC3D,MAAM,cAAc,GAAwB,iBAAiB,CAC3D,KAAK,CAAC,WAAW,CAClB,IAAI;QACH,YAAY,EAAE,KAAK;QACnB,QAAQ,EAAE,KAAK;KAChB,CAAA;IAED,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CACrB,sCACE,SAAS,EAAE,IAAA,oBAAU,EAAC;YACpB,yCAAyC,EAAE,cAAc,CAAC,YAAY;SACvE,CAAC,0BACoB,cAAc,CAAC,QAAQ,4BACrB,cAAc,CAAC,QAAQ,EAC/C,KAAK,EAAC,KAAK,EACX,IAAI,EAAC,cAAc,IAElB,KAAK,CAAC,QAAQ,CACZ,CACN,CAAC,CAAC,CAAC,CACF,sCACE,SAAS,EAAE,IAAA,oBAAU,EAAC;YACpB,wBAAwB,EAAE,cAAc,CAAC,QAAQ,KAAK,QAAQ;YAC9D,yCAAyC,EAAE,cAAc,CAAC,YAAY;SACvE,CAAC,IAED,KAAK,CAAC,QAAQ,CACZ,CACN,CAAA;AACH,CAAC,CAAA;AAnCY,QAAA,SAAS,aAmCrB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@financial-times/cp-content-pipeline-ui",
3
- "version": "3.0.1",
3
+ "version": "3.0.2",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -1,18 +1,14 @@
1
1
  import { ContentTree } from '@financial-times/content-tree'
2
- import React, { createContext } from 'react'
2
+ import React, { createContext, useContext } from 'react'
3
3
 
4
- export const ParagraphContext = createContext<
5
- { className?: string } | undefined
6
- >(undefined)
4
+ export const ParagraphContext = createContext<{ className: string } | null>(
5
+ null
6
+ )
7
7
 
8
8
  export default function Paragraph(
9
9
  props: React.PropsWithChildren<ContentTree.Paragraph>
10
10
  ) {
11
- return (
12
- <ParagraphContext.Consumer>
13
- {({ className } = { className: undefined }) => (
14
- <p {...{ className }}>{props.children}</p>
15
- )}
16
- </ParagraphContext.Consumer>
17
- )
11
+ const { className } = useContext(ParagraphContext) ?? { className: undefined }
12
+
13
+ return <p {...{ className }}>{props.children}</p>
18
14
  }
@@ -1,6 +1,6 @@
1
1
  import { ContentTree } from '@financial-times/content-tree'
2
2
  import { ScrollyImageFragment } from '@financial-times/cp-content-pipeline-client'
3
- import React from 'react'
3
+ import React, { useContext } from 'react'
4
4
  import { BreakpointGetter, FallbackImage, Sources } from '../ImageSet'
5
5
  import { ScrollyIDContext } from '.'
6
6
 
@@ -26,6 +26,8 @@ const scrollyGetBreakpoints: BreakpointGetter = (image) => {
26
26
  export function ScrollyImage({
27
27
  picture,
28
28
  }: ContentTree.ScrollyImage & ScrollyImageFragment) {
29
+ const scrollyId = useContext(ScrollyIDContext)
30
+
29
31
  if (!picture?.images) {
30
32
  throw new Error(
31
33
  `ScrollyImage has no images. Check that they are present in the query`
@@ -33,31 +35,27 @@ export function ScrollyImage({
33
35
  }
34
36
 
35
37
  return (
36
- <ScrollyIDContext.Consumer>
37
- {(scrollyId) => (
38
- <figure
39
- className="n-scrollytelling__figure n-content-image--full"
40
- data-scrollytelling-slide={scrollyId}
41
- >
42
- <picture>
43
- <Sources
44
- images={picture.images}
45
- getBreakpoints={scrollyGetBreakpoints}
46
- />
47
- <FallbackImage
48
- image={picture.fallbackImage}
49
- imageType={picture.imageType}
50
- className="n-scrollytelling__image"
51
- />
52
- </picture>
53
- {(picture.caption || picture.credit) && (
54
- <figcaption className="n-scrollytelling__caption n-scrollytelling__caption--has-caption">
55
- {picture.caption ? picture.caption + ' ' : ''}
56
- {picture.credit ? `© ${picture.credit}` : ''}
57
- </figcaption>
58
- )}
59
- </figure>
38
+ <figure
39
+ className="n-scrollytelling__figure n-content-image--full"
40
+ data-scrollytelling-slide={scrollyId}
41
+ >
42
+ <picture>
43
+ <Sources
44
+ images={picture.images}
45
+ getBreakpoints={scrollyGetBreakpoints}
46
+ />
47
+ <FallbackImage
48
+ image={picture.fallbackImage}
49
+ imageType={picture.imageType}
50
+ className="n-scrollytelling__image"
51
+ />
52
+ </picture>
53
+ {(picture.caption || picture.credit) && (
54
+ <figcaption className="n-scrollytelling__caption n-scrollytelling__caption--has-caption">
55
+ {picture.caption ? picture.caption + ' ' : ''}
56
+ {picture.credit ? `© ${picture.credit}` : ''}
57
+ </figcaption>
60
58
  )}
61
- </ScrollyIDContext.Consumer>
59
+ </figure>
62
60
  )
63
61
  }
@@ -1,10 +1,10 @@
1
- import React, { FC, PropsWithChildren, createContext } from 'react'
1
+ import React, { FC, PropsWithChildren, createContext, useContext } from 'react'
2
2
  import type { ContentTree } from '@financial-times/content-tree'
3
3
  import classnames from 'classnames'
4
4
  import type scrollytelling from '@financial-times/n-scrollytelling-image/server'
5
5
  import { ParagraphContext } from '../Paragraph'
6
6
 
7
- export const ScrollyIDContext = createContext<string | undefined>(undefined)
7
+ export const ScrollyIDContext = createContext<string | null>(null)
8
8
 
9
9
  export const ScrollyBlock: FC<
10
10
  PropsWithChildren<Omit<ContentTree.ScrollyBlock, 'children'>> & {
@@ -39,9 +39,8 @@ type ScrollySectionOptions = Pick<
39
39
  'display' | 'noBox' | 'position' | 'transition'
40
40
  >
41
41
 
42
- const ScrollySectionOptionsContext = createContext<
43
- ScrollySectionOptions | undefined
44
- >(undefined)
42
+ const ScrollySectionOptionsContext =
43
+ createContext<ScrollySectionOptions | null>(null)
45
44
 
46
45
  export const ScrollySection: FC<
47
46
  PropsWithChildren<ContentTree.ScrollySection>
@@ -58,56 +57,48 @@ type ScrollytellingDisplaySuffix =
58
57
 
59
58
  export const ScrollyCopy: FC<PropsWithChildren<ContentTree.ScrollyCopy>> = ({
60
59
  children,
61
- }) => (
62
- <ScrollyIDContext.Consumer>
63
- {(scrollyId) => (
64
- <ScrollySectionOptionsContext.Consumer>
65
- {(
66
- { display, noBox, position, transition } = {
67
- display: 'dark-background',
68
- position: 'center',
69
- }
70
- ) => {
71
- const displaySuffix: ScrollytellingDisplaySuffix =
72
- display === 'dark-background'
73
- ? 'background-dark'
74
- : 'background-light'
75
- return (
76
- <div
77
- className={classnames(
78
- 'n-scrollytelling__overlay-text-slide',
79
- `n-scrollytelling__overlay-text-slide--position-${position}`,
80
- {
81
- 'n-scrollytelling__overlay-text-slide-box--transparent':
82
- noBox,
83
- [`n-scrollytelling__overlay-text-slide-box--${displaySuffix}`]:
84
- display,
85
- [`n-scrollytelling__overlay-text-slide--${transition}`]:
86
- transition,
87
- }
88
- )}
89
- data-scrollytelling-text-slide={scrollyId}
90
- >
91
- <div
92
- className={classnames('n-scrollytelling__overlay-text-box', {
93
- 'n-scrollytelling__overlay-text-box--transparent': noBox,
94
- [`n-scrollytelling__overlay-text-box--${displaySuffix}`]:
95
- display,
96
- })}
97
- >
98
- <ParagraphContext.Provider
99
- value={{ className: 'n-scrollytelling__overlay-text' }}
100
- >
101
- <>{children}</>
102
- </ParagraphContext.Provider>
103
- </div>
104
- </div>
105
- )
106
- }}
107
- </ScrollySectionOptionsContext.Consumer>
108
- )}
109
- </ScrollyIDContext.Consumer>
110
- )
60
+ }) => {
61
+ const { display, noBox, position, transition } = useContext(
62
+ ScrollySectionOptionsContext
63
+ ) ?? {
64
+ display: 'dark-background',
65
+ position: 'center',
66
+ }
67
+
68
+ const scrollyId = useContext(ScrollyIDContext)
69
+
70
+ const displaySuffix: ScrollytellingDisplaySuffix =
71
+ display === 'dark-background' ? 'background-dark' : 'background-light'
72
+
73
+ return (
74
+ <div
75
+ className={classnames(
76
+ 'n-scrollytelling__overlay-text-slide',
77
+ `n-scrollytelling__overlay-text-slide--position-${position}`,
78
+ {
79
+ 'n-scrollytelling__overlay-text-slide-box--transparent': noBox,
80
+ [`n-scrollytelling__overlay-text-slide-box--${displaySuffix}`]:
81
+ display,
82
+ [`n-scrollytelling__overlay-text-slide--${transition}`]: transition,
83
+ }
84
+ )}
85
+ data-scrollytelling-text-slide={scrollyId}
86
+ >
87
+ <div
88
+ className={classnames('n-scrollytelling__overlay-text-box', {
89
+ 'n-scrollytelling__overlay-text-box--transparent': noBox,
90
+ [`n-scrollytelling__overlay-text-box--${displaySuffix}`]: display,
91
+ })}
92
+ >
93
+ <ParagraphContext.Provider
94
+ value={{ className: 'n-scrollytelling__overlay-text' }}
95
+ >
96
+ <>{children}</>
97
+ </ParagraphContext.Provider>
98
+ </div>
99
+ </div>
100
+ )
101
+ }
111
102
 
112
103
  export const ScrollyHeading: FC<
113
104
  PropsWithChildren<ContentTree.ScrollyHeading>
@@ -1,4 +1,4 @@
1
- import React from 'react'
1
+ import React, { useContext } from 'react'
2
2
  import type { ContentTreeWorkarounds } from '@financial-times/cp-content-pipeline-schema'
3
3
  import { ColumnSettingsContext } from '.'
4
4
  import { TableColumnSettings } from '@financial-times/cp-content-pipeline-schema/src/resolvers/content-tree/Workarounds'
@@ -8,40 +8,35 @@ export const TableCell = (
8
8
  props: React.PropsWithChildren<ContentTreeWorkarounds.TableCell> & {
9
9
  parentIndex: number
10
10
  }
11
- ) => (
12
- <ColumnSettingsContext.Consumer>
13
- {(allColumnSettings) => {
14
- const columnSettings: TableColumnSettings = allColumnSettings[
15
- props.parentIndex
16
- ] ?? {
17
- hideOnMobile: false,
18
- sortable: false,
19
- }
11
+ ) => {
12
+ const allColumnSettings = useContext(ColumnSettingsContext)
13
+ const columnSettings: TableColumnSettings = allColumnSettings[
14
+ props.parentIndex
15
+ ] ?? {
16
+ hideOnMobile: false,
17
+ sortable: false,
18
+ }
20
19
 
21
- return props.heading ? (
22
- <th
23
- className={classNames({
24
- 'n-content-body__table-cell--hide-mobile':
25
- columnSettings.hideOnMobile,
26
- })}
27
- data-column-sortable={columnSettings.sortable}
28
- data-o-table-data-type={columnSettings.sortType}
29
- scope="col"
30
- role="columnheader"
31
- >
32
- {props.children}
33
- </th>
34
- ) : (
35
- <td
36
- className={classNames({
37
- 'o-table__cell--numeric': columnSettings.sortType === 'number',
38
- 'n-content-body__table-cell--hide-mobile':
39
- columnSettings.hideOnMobile,
40
- })}
41
- >
42
- {props.children}
43
- </td>
44
- )
45
- }}
46
- </ColumnSettingsContext.Consumer>
47
- )
20
+ return props.heading ? (
21
+ <th
22
+ className={classNames({
23
+ 'n-content-body__table-cell--hide-mobile': columnSettings.hideOnMobile,
24
+ })}
25
+ data-column-sortable={columnSettings.sortable}
26
+ data-o-table-data-type={columnSettings.sortType}
27
+ scope="col"
28
+ role="columnheader"
29
+ >
30
+ {props.children}
31
+ </th>
32
+ ) : (
33
+ <td
34
+ className={classNames({
35
+ 'o-table__cell--numeric': columnSettings.sortType === 'number',
36
+ 'n-content-body__table-cell--hide-mobile': columnSettings.hideOnMobile,
37
+ })}
38
+ >
39
+ {props.children}
40
+ </td>
41
+ )
42
+ }