@twreporter/react-article-components 1.6.0 → 1.6.2-rc.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.
@@ -56,6 +56,10 @@ var _get = _interopRequireDefault(require("lodash/get"));
56
56
 
57
57
  var _map = _interopRequireDefault(require("lodash/map"));
58
58
 
59
+ var _smoothScroll = _interopRequireDefault(require("smooth-scroll/dist/smooth-scroll"));
60
+
61
+ var _anchor = require("../../constants/anchor");
62
+
59
63
  var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9, _templateObject10, _templateObject11, _templateObject12, _templateObject13, _templateObject14, _templateObject15, _templateObject16, _templateObject17, _templateObject18, _templateObject19, _templateObject20, _templateObject21, _templateObject22, _templateObject23;
60
64
 
61
65
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
@@ -203,12 +207,14 @@ var ClearFloat = /*#__PURE__*/_styledComponents["default"].div.withConfig({
203
207
  *
204
208
  * @export
205
209
  * @param {ElementData} [data={}]
210
+ * @param {boolean} isScrollingToAnchor - state of scrolling to an anchor or not
206
211
  * @returns
207
212
  */
208
213
 
209
214
 
210
215
  function renderElement() {
211
216
  var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
217
+ var isScrollingToAnchor = arguments.length > 1 ? arguments[1] : undefined;
212
218
  var isCenterAligned = data.alignment === _elementAlignment["default"].center || data.alignment === _elementAlignment["default"].centerSmall;
213
219
 
214
220
  switch (data.type) {
@@ -270,14 +276,16 @@ function renderElement() {
270
276
  return /*#__PURE__*/_react["default"].createElement(AlignRight, {
271
277
  key: data.id
272
278
  }, /*#__PURE__*/_react["default"].createElement(StyledEmbedded, {
273
- data: data
279
+ data: data,
280
+ isScrollingToAnchor: isScrollingToAnchor
274
281
  }));
275
282
  }
276
283
 
277
284
  case _elementAlignment["default"].centerSmall:
278
285
  return /*#__PURE__*/_react["default"].createElement(StyledEmbeddedNormal, {
279
286
  key: data.id,
280
- data: data
287
+ data: data,
288
+ isScrollingToAnchor: isScrollingToAnchor
281
289
  });
282
290
 
283
291
  case _elementAlignment["default"].center:
@@ -285,7 +293,8 @@ function renderElement() {
285
293
  {
286
294
  return /*#__PURE__*/_react["default"].createElement(StyledEmbedded, {
287
295
  key: data.id,
288
- data: data
296
+ data: data,
297
+ isScrollingToAnchor: isScrollingToAnchor
289
298
  });
290
299
  }
291
300
  }
@@ -382,36 +391,77 @@ function renderElement() {
382
391
  }
383
392
  }
384
393
 
385
- var Body = /*#__PURE__*/function (_PureComponent) {
386
- _inherits(Body, _PureComponent);
394
+ var Body = /*#__PURE__*/function (_Component) {
395
+ _inherits(Body, _Component);
387
396
 
388
397
  var _super = _createSuper(Body);
389
398
 
390
- function Body() {
399
+ function Body(props) {
391
400
  var _this;
392
401
 
393
402
  _classCallCheck(this, Body);
394
403
 
395
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
396
- args[_key] = arguments[_key];
397
- }
398
-
399
- _this = _super.call.apply(_super, [this].concat(args));
404
+ _this = _super.call(this, props);
400
405
 
401
406
  _defineProperty(_assertThisInitialized(_this), "tocManager", _tableOfContents["default"].createManager());
402
407
 
408
+ _defineProperty(_assertThisInitialized(_this), "_scrollStartHandler", function () {
409
+ _this._onStartScrollingToAnchor(true);
410
+ });
411
+
412
+ _defineProperty(_assertThisInitialized(_this), "_scrollStopHandler", function () {
413
+ // Wait for a short time to avoid trigger waypoint's onEnter() of infogram embed close to the anchor
414
+ setTimeout(function () {
415
+ return _this._onStartScrollingToAnchor(false);
416
+ }, _anchor.WAIT_AFTER_REACH_ANCHOR);
417
+ });
418
+
419
+ _defineProperty(_assertThisInitialized(_this), "_onStartScrollingToAnchor", function (isScrollingToAnchor, callback) {
420
+ _this.setState({
421
+ isScrollingToAnchor: isScrollingToAnchor
422
+ }, function () {
423
+ if (callback) {
424
+ callback();
425
+ }
426
+ });
427
+ });
428
+
403
429
  _defineProperty(_assertThisInitialized(_this), "_buildContentElement", function (data, index) {
404
430
  if (!data.id) {
405
431
  data.id = "body_element_".concat(index);
406
432
  }
407
433
 
408
- return renderElement(data);
434
+ return renderElement(data, _this.state.isScrollingToAnchor);
409
435
  });
410
436
 
437
+ _this.state = {
438
+ isScrollingToAnchor: false
439
+ };
411
440
  return _this;
412
441
  }
413
442
 
414
443
  _createClass(Body, [{
444
+ key: "componentDidMount",
445
+ value: function componentDidMount() {
446
+ // We apply smooth scroll only to ARTICLE_ANCHOR_SCROLL('article-anchor-scroll') selector
447
+ // ex: <a article-anchor-scroll="true" href="#..."" />
448
+ // eslint-disable-next-line no-new
449
+ new _smoothScroll["default"]("[".concat(_anchor.ARTICLE_ANCHOR_SCROLL, "]"), {
450
+ speed: _anchor.ANCHOR_SCROLL_DURATION,
451
+ speedAsDuration: true,
452
+ easing: 'easeInOutQuint',
453
+ emitEvents: true
454
+ });
455
+ document.addEventListener('scrollStart', this._scrollStartHandler, false);
456
+ document.addEventListener('scrollStop', this._scrollStopHandler, false);
457
+ }
458
+ }, {
459
+ key: "componentWillUnmount",
460
+ value: function componentWillUnmount() {
461
+ document.removeEventListener('scrollStart', this._scrollStartHandler);
462
+ document.removeEventListener('scrollStop', this._scrollStopHandler);
463
+ }
464
+ }, {
415
465
  key: "render",
416
466
  value: function render() {
417
467
  var _this2 = this;
@@ -439,13 +489,14 @@ var Body = /*#__PURE__*/function (_PureComponent) {
439
489
  return /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement(StyledBrief, {
440
490
  data: brief
441
491
  }), contentJsx, /*#__PURE__*/_react["default"].createElement(ClearFloat, null), enableTOC ? /*#__PURE__*/_react["default"].createElement(_tableOfContents["default"].React.TableOfContents, {
442
- manager: this.tocManager
492
+ manager: this.tocManager,
493
+ onStartScrollingToAnchor: this._onStartScrollingToAnchor
443
494
  }) : null);
444
495
  }
445
496
  }]);
446
497
 
447
498
  return Body;
448
- }(_react.PureComponent);
499
+ }(_react.Component);
449
500
 
450
501
  exports["default"] = Body;
451
502
 
@@ -7,17 +7,19 @@ Object.defineProperty(exports, "__esModule", {
7
7
  });
8
8
  exports["default"] = void 0;
9
9
 
10
- var _mediaQuery = _interopRequireDefault(require("@twreporter/core/lib/utils/media-query"));
10
+ var _react = _interopRequireWildcard(require("react"));
11
11
 
12
12
  var _propTypes = _interopRequireDefault(require("prop-types"));
13
13
 
14
- var _body = _interopRequireDefault(require("../../constants/prop-types/body"));
14
+ var _styledComponents = _interopRequireWildcard(require("styled-components"));
15
15
 
16
- var _react = _interopRequireWildcard(require("react"));
16
+ var _get = _interopRequireDefault(require("lodash/get"));
17
17
 
18
- var _css = _interopRequireDefault(require("../../constants/css"));
18
+ var _mediaQuery = _interopRequireDefault(require("@twreporter/core/lib/utils/media-query"));
19
19
 
20
- var _styledComponents = _interopRequireWildcard(require("styled-components"));
20
+ var _body = _interopRequireDefault(require("../../constants/prop-types/body"));
21
+
22
+ var _css = _interopRequireDefault(require("../../constants/css"));
21
23
 
22
24
  var _theme = _interopRequireDefault(require("../../constants/theme"));
23
25
 
@@ -25,16 +27,16 @@ var _typography = _interopRequireDefault(require("../../constants/typography"));
25
27
 
26
28
  var _color = _interopRequireDefault(require("../../constants/color"));
27
29
 
28
- var _get = _interopRequireDefault(require("lodash/get"));
30
+ var _anchor = require("../../constants/anchor");
29
31
 
30
32
  var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6;
31
33
 
34
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
35
+
32
36
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
33
37
 
34
38
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
35
39
 
36
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
37
-
38
40
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
39
41
 
40
42
  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
@@ -121,11 +123,18 @@ var Infobox = /*#__PURE__*/function (_PureComponent) {
121
123
 
122
124
  var title = _.get(data, ['content', 0, 'title'], '');
123
125
 
124
- return contentHtmlString ? /*#__PURE__*/_react["default"].createElement(Container, {
126
+ var anchorRegex = /<a([^>]*)>/g;
127
+ var hashRegex = /href={?["']#/;
128
+ var mutatedContentHtmlString = contentHtmlString === null || contentHtmlString === void 0 ? void 0 : contentHtmlString.replace(anchorRegex, function (anchorString, attrs) {
129
+ // Here we insert a custom attribute 'ARTICLE_ANCHOR_SCROLL' in order to apply
130
+ // smooth scroll effect on <a href="#..."> anchors inside infobox
131
+ return hashRegex.exec(anchorString) ? "<a ".concat(_anchor.ARTICLE_ANCHOR_SCROLL, "=\"true\" ").concat(attrs, ">") : anchorString;
132
+ });
133
+ return mutatedContentHtmlString ? /*#__PURE__*/_react["default"].createElement(Container, {
125
134
  className: className
126
135
  }, title ? /*#__PURE__*/_react["default"].createElement(Title, null, title) : null, /*#__PURE__*/_react["default"].createElement(Content, {
127
136
  dangerouslySetInnerHTML: {
128
- __html: contentHtmlString
137
+ __html: mutatedContentHtmlString
129
138
  }
130
139
  })) : null;
131
140
  }
@@ -17,6 +17,8 @@ var _tableOfContents = _interopRequireDefault(require("@twreporter/react-compone
17
17
 
18
18
  var _map = _interopRequireDefault(require("lodash/map"));
19
19
 
20
+ var _anchor = require("../../constants/anchor");
21
+
20
22
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
21
23
 
22
24
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
@@ -136,7 +138,8 @@ var TableOfContents = /*#__PURE__*/function (_React$PureComponent) {
136
138
 
137
139
  var _this$props = this.props,
138
140
  className = _this$props.className,
139
- manager = _this$props.manager;
141
+ manager = _this$props.manager,
142
+ onStartScrollingToAnchor = _this$props.onStartScrollingToAnchor;
140
143
  var isExpanded = this.state.isExpanded;
141
144
  return /*#__PURE__*/_react["default"].createElement("div", {
142
145
  className: "hidden-print",
@@ -144,13 +147,21 @@ var TableOfContents = /*#__PURE__*/function (_React$PureComponent) {
144
147
  }, /*#__PURE__*/_react["default"].createElement(_tableOfContents["default"].React.TableOfContents, {
145
148
  className: className,
146
149
  manager: manager,
150
+ scrollDuration: _anchor.ANCHOR_SCROLL_DURATION,
147
151
  render: function render(anchors, highlightAnchor, handleAnchorClick) {
148
152
  var anchorsJSX = _.map(anchors, function (anchor) {
149
153
  var toHighlight = anchor === highlightAnchor;
150
154
  return /*#__PURE__*/_react["default"].createElement(Styled.TOCRow, {
151
155
  key: anchor.anchorID,
152
156
  onClick: function onClick() {
153
- return handleAnchorClick(anchor.anchorID);
157
+ onStartScrollingToAnchor(true, function () {
158
+ return handleAnchorClick(anchor.anchorID, function () {
159
+ // Wait for a short time to avoid trigger waypoint's onEnter() of infogram embed close to the anchor
160
+ setTimeout(function () {
161
+ return onStartScrollingToAnchor(false);
162
+ }, _anchor.WAIT_AFTER_REACH_ANCHOR);
163
+ });
164
+ });
154
165
  }
155
166
  }, /*#__PURE__*/_react["default"].createElement(Styled.TOCIndicator, {
156
167
  toHighlight: toHighlight,
@@ -178,7 +189,8 @@ var TableOfContents = /*#__PURE__*/function (_React$PureComponent) {
178
189
 
179
190
  _defineProperty(TableOfContents, "propTypes", {
180
191
  className: _propTypes["default"].string,
181
- manager: _tableOfContents["default"].React.TableOfContents.propTypes.manager
192
+ manager: _tableOfContents["default"].React.TableOfContents.propTypes.manager,
193
+ onStartScrollingToAnchor: _propTypes["default"].func
182
194
  });
183
195
 
184
196
  _defineProperty(TableOfContents, "defaultProps", {
@@ -3,6 +3,12 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.relatedPostAnchor = void 0;
7
- var relatedPostAnchor = 'related-post-anchor';
8
- exports.relatedPostAnchor = relatedPostAnchor;
6
+ exports.ANCHOR_SCROLL_DURATION = exports.WAIT_AFTER_REACH_ANCHOR = exports.ARTICLE_ANCHOR_SCROLL = exports.RELATED_POST_ANCHOR_ID = void 0;
7
+ var RELATED_POST_ANCHOR_ID = 'related-post-anchor';
8
+ exports.RELATED_POST_ANCHOR_ID = RELATED_POST_ANCHOR_ID;
9
+ var ARTICLE_ANCHOR_SCROLL = 'article-anchor-scroll';
10
+ exports.ARTICLE_ANCHOR_SCROLL = ARTICLE_ANCHOR_SCROLL;
11
+ var WAIT_AFTER_REACH_ANCHOR = 20;
12
+ exports.WAIT_AFTER_REACH_ANCHOR = WAIT_AFTER_REACH_ANCHOR;
13
+ var ANCHOR_SCROLL_DURATION = 500;
14
+ exports.ANCHOR_SCROLL_DURATION = ANCHOR_SCROLL_DURATION;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twreporter/react-article-components",
3
- "version": "1.6.0",
3
+ "version": "1.6.2-rc.0",
4
4
  "description": "The Reporter react article components, which are used in article page",
5
5
  "main": "lib/components/article-page.js",
6
6
  "repository": "https://github.com/twreporter/twreporter-npm-packages.git",
@@ -24,21 +24,21 @@
24
24
  "webpack-dev-server": "^3.7.2"
25
25
  },
26
26
  "dependencies": {
27
- "@twreporter/core": "^1.4.1",
28
- "@twreporter/react-components": "^8.11.0",
27
+ "@twreporter/core": "^1.4.2-rc.0",
28
+ "@twreporter/react-components": "^8.11.1-rc.0",
29
29
  "@twreporter/redux": "^7.2.2",
30
- "@twreporter/universal-header": "^2.2.11",
30
+ "@twreporter/universal-header": "^2.2.12-rc.0",
31
31
  "howler": "^2.2.3",
32
32
  "lodash": "^4.17.11",
33
33
  "memoize-one": "^5.0.5",
34
34
  "prop-types": "^15.0.0",
35
35
  "react": "^16.3.0",
36
- "react-scroll": "^1.8.7",
37
36
  "react-waypoint": "^9.0.2",
37
+ "smooth-scroll": "16.1.3",
38
38
  "styled-components": "^4.0.0"
39
39
  },
40
40
  "files": [
41
41
  "lib"
42
42
  ],
43
- "gitHead": "22127d74e0d0433e87b427aed82394972cade963"
43
+ "gitHead": "adbbd91639cb9a74438108b97083294acf57d8cf"
44
44
  }