@twreporter/react-article-components 2.2.2-rc.0 → 2.3.0-rc.1

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
@@ -3,6 +3,34 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [2.3.0-rc.1](https://github.com/twreporter/twreporter-npm-packages/compare/@twreporter/react-article-components@2.3.0-rc.0...@twreporter/react-article-components@2.3.0-rc.1) (2024-07-08)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * fix comments ([6084a28](https://github.com/twreporter/twreporter-npm-packages/commit/6084a289944823cf43e8c063f5c797920d454ee9))
12
+ * naming ([87d00f4](https://github.com/twreporter/twreporter-npm-packages/commit/87d00f456312ef1e7a522301e3e2d5c23c244d30))
13
+
14
+
15
+ ### Features
16
+
17
+ * **react-article-components:** full screen image version2 ([49b1495](https://github.com/twreporter/twreporter-npm-packages/commit/49b1495a03f4b1c181e0b9fafc378f094fe651b7))
18
+
19
+
20
+
21
+
22
+
23
+ # [2.3.0-rc.0](https://github.com/twreporter/twreporter-npm-packages/compare/@twreporter/react-article-components@2.2.2-rc.0...@twreporter/react-article-components@2.3.0-rc.0) (2024-07-08)
24
+
25
+
26
+ ### Features
27
+
28
+ * **react-article-components:** centered-quote font size ([e20ef32](https://github.com/twreporter/twreporter-npm-packages/commit/e20ef32591d29f8ca4e189d32dfce80781dc7e0e))
29
+
30
+
31
+
32
+
33
+
6
34
  ## [2.2.2-rc.0](https://github.com/twreporter/twreporter-npm-packages/compare/@twreporter/react-article-components@2.2.1...@twreporter/react-article-components@2.2.2-rc.0) (2024-07-08)
7
35
 
8
36
  **Note:** Version bump only for package @twreporter/react-article-components
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
 
3
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
@@ -12,11 +13,12 @@ var _css = _interopRequireDefault(require("../../constants/css"));
12
13
  var _theme = _interopRequireDefault(require("../../constants/theme"));
13
14
  var _typography = _interopRequireDefault(require("../../constants/typography"));
14
15
  var _color = require("@twreporter/core/lib/constants/color");
16
+ var _mediaQuery = _interopRequireDefault(require("@twreporter/core/lib/utils/media-query"));
15
17
  var _get = _interopRequireDefault(require("lodash/get"));
18
+ var _templateObject; // lodash
16
19
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
17
20
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
18
21
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
19
- function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
20
22
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
21
23
  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, _toPropertyKey(descriptor.key), descriptor); } }
22
24
  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
@@ -29,16 +31,19 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
29
31
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
30
32
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
31
33
  function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
32
- function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } // lodash
34
+ function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
35
+ function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
33
36
  var _ = {
34
37
  get: _get["default"]
35
38
  };
36
39
  var QuoteContent = /*#__PURE__*/_styledComponents["default"].blockquote.withConfig({
37
40
  displayName: "centered-quote__QuoteContent",
38
41
  componentId: "oc409x-0"
39
- })(["white-space:pre-wrap;margin:0;font-weight:", ";font-size:", "px;line-height:1.56;letter-spacing:1.1px;text-align:center;"], _typography["default"].font.weight.normal, function (props) {
42
+ })(["white-space:pre-wrap;margin:0;font-weight:", ";font-size:", "px;line-height:1.56;letter-spacing:1.1px;text-align:center;", ""], _typography["default"].font.weight.normal, function (props) {
40
43
  return props.theme.fontSizeOffset + 32;
41
- });
44
+ }, _mediaQuery["default"].tabletAndBelow(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n font-size: ", "px;\n "])), function (props) {
45
+ return props.theme.fontSizeOffset + 24;
46
+ }));
42
47
  var QuoteBy = /*#__PURE__*/_styledComponents["default"].cite.withConfig({
43
48
  displayName: "centered-quote__QuoteBy",
44
49
  componentId: "oc409x-1"
@@ -1,10 +1,11 @@
1
1
  "use strict";
2
2
 
3
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
6
7
  exports["default"] = void 0;
7
- var _react = _interopRequireDefault(require("react"));
8
+ var _react = _interopRequireWildcard(require("react"));
8
9
  var _styledComponents = _interopRequireWildcard(require("styled-components"));
9
10
  var _propTypes = _interopRequireDefault(require("prop-types"));
10
11
  var _storageUrlProcessor = require("@twreporter/core/lib/utils/storage-url-processor");
@@ -19,24 +20,16 @@ var _imgWithPlaceholder = _interopRequireDefault(require("../../constants/prop-t
19
20
  var _get = _interopRequireDefault(require("lodash/get"));
20
21
  var _map = _interopRequireDefault(require("lodash/map"));
21
22
  var _debounce = _interopRequireDefault(require("lodash/debounce"));
23
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
22
24
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
23
25
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
24
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
25
- function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
26
26
  function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
27
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
28
- 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, _toPropertyKey(descriptor.key), descriptor); } }
29
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
30
- function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
31
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
32
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
33
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
34
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
35
- function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
36
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
37
- function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
38
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
39
- function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } // @twreporter
27
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
28
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
29
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
30
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
31
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
32
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } // @twreporter
40
33
  var PlaceholderIcon = function PlaceholderIcon(props) {
41
34
  return /*#__PURE__*/_react["default"].createElement("svg", props, /*#__PURE__*/_react["default"].createElement("title", null, "Fill 1"), /*#__PURE__*/_react["default"].createElement("path", {
42
35
  d: "M5 112.563a5.001 5.001 0 0 1-5-5V4.999C0 3.298.866 1.713 2.298.794A5.003 5.003 0 0 1 7.08.451l42.724 19.521a5 5 0 0 1-4.156 9.097L10 12.783V99.78l49.843-22.775V32.014a5 5 0 0 1 3.669-4.82l37.105-10.247a4.999 4.999 0 0 1 6.331 4.819v67.44a5.003 5.003 0 0 1-6.142 4.868l-20.106-4.716a5 5 0 0 1 2.284-9.736l13.965 3.275V28.332L69.844 35.82v44.4a5 5 0 0 1-2.922 4.549L7.078 112.11a4.996 4.996 0 0 1-2.079.451",
@@ -59,11 +52,32 @@ var objectFitConsts = {
59
52
  contain: 'contain',
60
53
  cover: 'cover'
61
54
  };
55
+ var CrossIconPos = Object.freeze({
56
+ INSIDE: 'inside',
57
+ TOP_RIGHT: 'top-right',
58
+ RIGHT_TOP: 'right-top'
59
+ });
60
+
61
+ // padding: 16px + width: 24px => 40px
62
+ var iconPadding = 40;
63
+ var CrossIconPosCss = function CrossIconPosCss(position) {
64
+ switch (position) {
65
+ case CrossIconPos.TOP_RIGHT:
66
+ return (0, _styledComponents.css)(["top:-", "px;right:0px;"], iconPadding);
67
+ case CrossIconPos.RIGHT_TOP:
68
+ return (0, _styledComponents.css)(["top:0px;right:-", "px;"], iconPadding);
69
+ case CrossIconPos.INSIDE:
70
+ default:
71
+ return (0, _styledComponents.css)(["top:0px;right:0px;"]);
72
+ }
73
+ };
62
74
  var ImgContainer = /*#__PURE__*/_styledComponents["default"].div.withConfig({
63
75
  displayName: "img-with-placeholder__ImgContainer",
64
76
  componentId: "c6mvsc-0"
65
- })(["position:relative;overflow:hidden;width:100%;", ""], function (props) {
77
+ })(["position:relative;overflow:hidden;width:100%;", " ", ""], function (props) {
66
78
  return props.$heightString;
79
+ }, function (props) {
80
+ return props.$clickable ? 'cursor: zoom-in;' : '';
67
81
  });
68
82
  var ImgPlaceholder = /*#__PURE__*/_styledComponents["default"].div.withConfig({
69
83
  displayName: "img-with-placeholder__ImgPlaceholder",
@@ -114,236 +128,245 @@ var FullScreenImageMask = /*#__PURE__*/_styledComponents["default"].div.withConf
114
128
  var FullScreenImage = /*#__PURE__*/_styledComponents["default"].div.withConfig({
115
129
  displayName: "img-with-placeholder__FullScreenImage",
116
130
  componentId: "c6mvsc-7"
117
- })(["position:relative;img{max-width:90vw;max-height:90vh;}"]);
131
+ })(["position:relative;img{max-width:100vw;max-height:100vh;}"]);
118
132
  var CrossIcon = /*#__PURE__*/_styledComponents["default"].div.withConfig({
119
133
  displayName: "img-with-placeholder__CrossIcon",
120
134
  componentId: "c6mvsc-8"
121
- })(["cursor:pointer;position:absolute;top:0px;right:-40px;height:24px;width:24px;svg{background-color:", ";}"], _color.colorGrayscale.white);
135
+ })(["cursor:pointer;position:absolute;", " height:24px;width:24px;svg{background-color:", ";}"], function (props) {
136
+ return CrossIconPosCss(props.$crossIconPos);
137
+ }, _color.colorGrayscale.white);
122
138
 
123
139
  /**
124
140
  * An image element with placeholder.
125
141
  * The width and height of the image are required to preserve the space on the page for image.
126
- *
127
- * @class Image
128
- * @extends {React.PureComponent}
129
142
  */
130
- var Img = exports["default"] = /*#__PURE__*/function (_React$PureComponent) {
131
- _inherits(Img, _React$PureComponent);
132
- var _super = _createSuper(Img);
133
- function Img(props) {
134
- var _this;
135
- _classCallCheck(this, Img);
136
- _this = _super.call(this, props);
137
- _defineProperty(_assertThisInitialized(_this), "_handleWindowResize", function () {
138
- var windowWidth = window.innerWidth;
139
- _this.setState({
140
- isMobile: windowWidth < _mediaQuery.DEFAULT_SCREEN.tablet.minWidth
141
- });
142
- });
143
- _this.state = {
144
- isLoaded: false,
145
- toShowPlaceholder: true,
146
- showFullScreenImg: false,
147
- isMobile: false
148
- };
149
- _this._img = /*#__PURE__*/_react["default"].createRef();
150
- _this.handleImageLoaded = _this.handleImageLoaded.bind(_assertThisInitialized(_this));
151
- _this.handleWindowResize = _.debounce(_this._handleWindowResize, 500).bind(_assertThisInitialized(_this));
152
- _this._isMounted = false;
153
- _this._supportObjectFit = true;
154
- return _this;
155
- }
156
- _createClass(Img, [{
157
- key: "componentDidMount",
158
- value: function componentDidMount() {
159
- // Check if browser support css object-fit.
160
- // Ref: https://github.com/anselmh/object-fit/blob/c6e275b099caf59ca44bfc5cbbaf4c388ace9980/src/polyfill.object-fit.core.js#L396
161
- this._supportObjectFit = 'objectFit' in document.documentElement.style === true;
162
- this._isMounted = true;
163
- // If the browser has cached the image already, the `load` event of `<img>` will never be triggered.
164
- // Hence, we need to trigger `handleImageLoaded` manually.
165
- if (_.get(this._img.current, 'complete')) {
166
- this.handleImageLoaded();
167
- }
168
- window.addEventListener('resize', this.handleWindowResize);
169
- this.handleWindowResize();
170
- }
171
- }, {
172
- key: "componentWillUnmount",
173
- value: function componentWillUnmount() {
174
- this._isMounted = false;
175
- window.removeEventListener('resize', this.handleWindowResize);
176
- }
177
- }, {
178
- key: "handleImageLoaded",
179
- value: function handleImageLoaded() {
180
- var _this2 = this;
181
- // Progressive image
182
- // Let user see the blur image,
183
- // and slowly make the blur image clearer
143
+ var Img = function Img(_ref) {
144
+ var _ref$alt = _ref.alt,
145
+ alt = _ref$alt === void 0 ? '' : _ref$alt,
146
+ _ref$className = _ref.className,
147
+ className = _ref$className === void 0 ? '' : _ref$className,
148
+ _ref$defaultImage = _ref.defaultImage,
149
+ defaultImage = _ref$defaultImage === void 0 ? {} : _ref$defaultImage,
150
+ _ref$imgPlaceholderSr = _ref.imgPlaceholderSrc,
151
+ imgPlaceholderSrc = _ref$imgPlaceholderSr === void 0 ? '' : _ref$imgPlaceholderSr,
152
+ _ref$placeholderNoBlu = _ref.placeholderNoBlur,
153
+ placeholderNoBlur = _ref$placeholderNoBlu === void 0 ? false : _ref$placeholderNoBlu,
154
+ _ref$noImgPlaceholder = _ref.noImgPlaceholder,
155
+ noImgPlaceholder = _ref$noImgPlaceholder === void 0 ? false : _ref$noImgPlaceholder,
156
+ _ref$imgProps = _ref.imgProps,
157
+ imgProps = _ref$imgProps === void 0 ? {} : _ref$imgProps,
158
+ _ref$imageSet = _ref.imageSet,
159
+ imageSet = _ref$imageSet === void 0 ? [] : _ref$imageSet,
160
+ objectFit = _ref.objectFit,
161
+ objectPosition = _ref.objectPosition,
162
+ _ref$sizes = _ref.sizes,
163
+ sizes = _ref$sizes === void 0 ? '' : _ref$sizes,
164
+ _ref$clickable = _ref.clickable,
165
+ clickable = _ref$clickable === void 0 ? false : _ref$clickable;
166
+ var themeContext = (0, _react.useContext)(_styledComponents.ThemeContext);
167
+ var _useState = (0, _react.useState)(false),
168
+ _useState2 = _slicedToArray(_useState, 2),
169
+ isLoaded = _useState2[0],
170
+ setIsLoaded = _useState2[1];
171
+ var _useState3 = (0, _react.useState)(true),
172
+ _useState4 = _slicedToArray(_useState3, 2),
173
+ toShowPlaceholder = _useState4[0],
174
+ setToShowPlaceholder = _useState4[1];
175
+ var _useState5 = (0, _react.useState)(false),
176
+ _useState6 = _slicedToArray(_useState5, 2),
177
+ showFullScreenImg = _useState6[0],
178
+ setShowFullScreenImg = _useState6[1];
179
+ var _useState7 = (0, _react.useState)(false),
180
+ _useState8 = _slicedToArray(_useState7, 2),
181
+ isMobile = _useState8[0],
182
+ setIsMobile = _useState8[1];
183
+ var imgRef = (0, _react.useRef)(null);
184
+ var _isMounted = (0, _react.useRef)(true);
185
+ var _useState9 = (0, _react.useState)(true),
186
+ _useState10 = _slicedToArray(_useState9, 2),
187
+ supportObjectFit = _useState10[0],
188
+ setSupportObjectFit = _useState10[1];
189
+ var fullScreenImageRef = (0, _react.useRef)(null);
190
+ var _useState11 = (0, _react.useState)(CrossIconPos.INSIDE),
191
+ _useState12 = _slicedToArray(_useState11, 2),
192
+ crossIconPos = _useState12[0],
193
+ setCrossIconPos = _useState12[1];
194
+ var handleImageLoaded = function handleImageLoaded() {
195
+ // Progressive image
196
+ // Let user see the blur image,
197
+ // and slowly make the blur image clearer
184
198
 
185
- // in order to make sure users see the blur image,
186
- // delay the clear image rendering
187
- setTimeout(function () {
188
- if (_this2._isMounted) {
189
- _this2.setState({
190
- isLoaded: true
191
- });
199
+ // in order to make sure users see the blur image,
200
+ // delay the clear image rendering
201
+ setTimeout(function () {
202
+ if (_isMounted.current) {
203
+ setIsLoaded(true);
204
+ }
205
+ }, 500);
206
+ // after clear image rendered, not display placeholder anymore
207
+ setTimeout(function () {
208
+ if (_isMounted.current) {
209
+ setToShowPlaceholder(false);
210
+ }
211
+ }, 1500);
212
+ };
213
+ var checkFullScreenImageSize = function checkFullScreenImageSize() {
214
+ if (fullScreenImageRef.current) {
215
+ var img = fullScreenImageRef.current;
216
+ var imgWidth = img.offsetWidth;
217
+ var imgHeight = img.offsetHeight;
218
+ var vw = window.innerWidth;
219
+ var vh = window.innerHeight;
220
+ if (imgWidth === vw) {
221
+ if (vh - imgHeight < iconPadding * 2) {
222
+ setCrossIconPos(CrossIconPos.INSIDE);
223
+ } else {
224
+ setCrossIconPos(CrossIconPos.TOP_RIGHT);
192
225
  }
193
- }, 500);
194
-
195
- // after clear image rendered, not display placeholder anymore
196
- setTimeout(function () {
197
- if (_this2._isMounted) {
198
- _this2.setState({
199
- toShowPlaceholder: false
200
- });
226
+ } else if (imgHeight === vh) {
227
+ if (vw - imgWidth < iconPadding * 2) {
228
+ setCrossIconPos(CrossIconPos.INSIDE);
229
+ } else {
230
+ setCrossIconPos(CrossIconPos.RIGHT_TOP);
201
231
  }
202
- }, 1500);
203
- }
204
- }, {
205
- key: "_renderImagePlaceholder",
206
- value: function _renderImagePlaceholder() {
207
- var toShowPlaceholder = this.state.toShowPlaceholder;
208
- var _this$props = this.props,
209
- imgPlaceholderSrc = _this$props.imgPlaceholderSrc,
210
- placeholderNoBlur = _this$props.placeholderNoBlur,
211
- noImgPlaceholder = _this$props.noImgPlaceholder;
212
- if (noImgPlaceholder) {
213
- return null;
214
- }
215
- if (imgPlaceholderSrc) {
216
- return /*#__PURE__*/_react["default"].createElement(ImgPlaceholder, {
217
- $src: (0, _storageUrlProcessor.replaceGCSUrlOrigin)(imgPlaceholderSrc),
218
- $toShow: toShowPlaceholder,
219
- $noBlur: placeholderNoBlur
220
- });
232
+ } else {
233
+ // default
234
+ setCrossIconPos(CrossIconPos.INSIDE);
221
235
  }
222
- // render default placeholder
223
- return /*#__PURE__*/_react["default"].createElement(Placeholder, {
224
- $toShow: toShowPlaceholder
225
- }, /*#__PURE__*/_react["default"].createElement(PlaceholderIcon, null));
226
236
  }
227
- }, {
228
- key: "render",
229
- value: function render() {
230
- var _this$context,
231
- _this3 = this;
232
- var _this$state = this.state,
233
- isLoaded = _this$state.isLoaded,
234
- showFullScreenImg = _this$state.showFullScreenImg,
235
- isMobile = _this$state.isMobile;
236
- var _this$props2 = this.props,
237
- alt = _this$props2.alt,
238
- className = _this$props2.className,
239
- imgProps = _this$props2.imgProps,
240
- imageSet = _this$props2.imageSet,
241
- defaultImage = _this$props2.defaultImage,
242
- objectFit = _this$props2.objectFit,
243
- objectPosition = _this$props2.objectPosition,
244
- sizes = _this$props2.sizes,
245
- clickable = _this$props2.clickable;
246
- var releaseBranch = (this === null || this === void 0 || (_this$context = this.context) === null || _this$context === void 0 ? void 0 : _this$context.releaseBranch) || _releaseBranch["default"].release;
247
- var openFullScreen = function openFullScreen() {
248
- if (isMobile) return;
249
- _this3.setState({
250
- showFullScreenImg: true
251
- });
252
- document.body.classList.add('disable-scroll');
253
- };
254
- var closeFullScreen = function closeFullScreen() {
255
- _this3.setState({
256
- showFullScreenImg: false
257
- });
258
- document.body.classList.remove('disable-scroll');
259
- };
260
- var appendedClassName = className + ' avoid-break';
261
- var defaultImageOriginalUrl = _.get(defaultImage, 'url');
262
- /* Render placeholder only if no valid image is given */
263
- if (!defaultImageOriginalUrl && (!imageSet || imageSet.length === 0)) {
264
- return /*#__PURE__*/_react["default"].createElement(ImgContainer, {
265
- className: appendedClassName,
266
- $heightString: "height: 100%;"
267
- }, this._renderImagePlaceholder());
237
+ };
238
+ var handleESCClick = _.debounce(function (e) {
239
+ if (showFullScreenImg) {
240
+ if (e.key === 'Escape') {
241
+ closeFullScreen();
268
242
  }
269
- var srcset = (0, _image.getSrcsetString)(imageSet);
270
- var isObjectFit = Boolean(objectFit);
271
- var heightWidthRatio = _.get(defaultImage, 'height') / _.get(defaultImage, 'width');
272
- if (isObjectFit && !heightWidthRatio) {
273
- console.warn('Warning on Img component:', 'The `objecFit` is set, but no valid height/width ratio of `props.defaultImage` is given.', '`props.defaultImage`:', defaultImage);
274
- }
275
- var defaultImageSrc = (0, _storageUrlProcessor.replaceGCSUrlOrigin)(_.get(defaultImage, 'url'));
276
- return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement(ImgContainer, {
277
- className: appendedClassName,
278
- $heightString: isObjectFit ? "height: 100%;" : "padding-top: ".concat(heightWidthRatio * 100, "%;"),
279
- onClick: clickable ? openFullScreen : undefined
280
- }, this._renderImagePlaceholder(), /*#__PURE__*/_react["default"].createElement(ImgBox, {
281
- $toShow: isLoaded
282
- }, isObjectFit ? /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement(ImgWithObjectFit, _extends({
283
- alt: alt,
284
- $objectFit: objectFit,
285
- $objectPosition: objectPosition,
286
- onLoad: this.handleImageLoaded,
287
- ref: this._img,
288
- sizes: this._supportObjectFit ? sizes : '',
289
- src: defaultImageSrc,
290
- srcSet: this._supportObjectFit ? srcset : '',
291
- hide: !this._supportObjectFit
292
- }, imgProps)), this._supportObjectFit ? null : /*#__PURE__*/_react["default"].createElement(FallbackObjectFitImg, {
293
- $url: _.get(defaultImage, 'url'),
294
- $objectFit: objectFit,
295
- $objectPosition: objectPosition
296
- })) : /*#__PURE__*/_react["default"].createElement("img", _extends({
297
- alt: alt,
298
- onLoad: this.handleImageLoaded,
299
- ref: this._img,
300
- sizes: sizes,
301
- src: defaultImageSrc,
302
- srcSet: srcset
303
- }, imgProps)))), showFullScreenImg && /*#__PURE__*/_react["default"].createElement(_rwd.DesktopAndAbove, null, /*#__PURE__*/_react["default"].createElement(FullScreenImageMask, {
304
- onClick: closeFullScreen
305
- }, /*#__PURE__*/_react["default"].createElement(FullScreenImage, null, /*#__PURE__*/_react["default"].createElement("img", {
306
- alt: alt,
307
- ref: this._img,
308
- sizes: sizes,
309
- src: defaultImageSrc,
310
- srcSet: srcset
311
- }), /*#__PURE__*/_react["default"].createElement(CrossIcon, null, /*#__PURE__*/_react["default"].createElement(_icon.Cross, {
312
- releaseBranch: releaseBranch
313
- }))))));
314
243
  }
315
- }]);
316
- return Img;
317
- }(_react["default"].PureComponent);
318
- _defineProperty(Img, "contextType", _styledComponents.ThemeContext);
319
- _defineProperty(Img, "propTypes", {
244
+ }, 500);
245
+ var handleWindowResize = _.debounce(function () {
246
+ var windowWidth = window.innerWidth;
247
+ if (windowWidth <= _mediaQuery.DEFAULT_SCREEN.tablet.minWidth) {
248
+ setIsMobile(true);
249
+ closeFullScreen();
250
+ } else {
251
+ setIsMobile(false);
252
+ }
253
+ checkFullScreenImageSize();
254
+ }, 100);
255
+ (0, _react.useEffect)(function () {
256
+ // Check if browser support css object-fit.
257
+ // Ref: https://github.com/anselmh/object-fit/blob/c6e275b099caf59ca44bfc5cbbaf4c388ace9980/src/polyfill.object-fit.core.js#L396
258
+ setSupportObjectFit('objectFit' in document.documentElement.style);
259
+ _isMounted.current = true;
260
+ // If the browser has cached the image already, the `load` event of `<img>` will never be triggered.
261
+ // Hence, we need to trigger `handleImageLoaded` manually.
262
+ if (_.get(imgRef.current, 'complete')) {
263
+ handleImageLoaded();
264
+ }
265
+ window.addEventListener('resize', handleWindowResize);
266
+ handleWindowResize();
267
+ window.addEventListener('keydown', handleESCClick);
268
+ return function () {
269
+ _isMounted.current = false;
270
+ window.removeEventListener('resize', handleWindowResize);
271
+ window.removeEventListener('keydown', handleESCClick);
272
+ };
273
+ }, []);
274
+ (0, _react.useEffect)(function () {
275
+ checkFullScreenImageSize();
276
+ }, [showFullScreenImg]);
277
+ var openFullScreen = function openFullScreen() {
278
+ if (isMobile) return;
279
+ setShowFullScreenImg(true);
280
+ document.body.classList.add('disable-scroll');
281
+ };
282
+ var closeFullScreen = function closeFullScreen() {
283
+ setShowFullScreenImg(false);
284
+ document.body.classList.remove('disable-scroll');
285
+ };
286
+ var renderImagePlaceholder = function renderImagePlaceholder() {
287
+ if (noImgPlaceholder) return null;
288
+ if (imgPlaceholderSrc) {
289
+ return /*#__PURE__*/_react["default"].createElement(ImgPlaceholder, {
290
+ $src: (0, _storageUrlProcessor.replaceGCSUrlOrigin)(imgPlaceholderSrc),
291
+ $toShow: toShowPlaceholder,
292
+ $noBlur: placeholderNoBlur
293
+ });
294
+ }
295
+ // render default placeholder
296
+ return /*#__PURE__*/_react["default"].createElement(Placeholder, {
297
+ $toShow: toShowPlaceholder
298
+ }, /*#__PURE__*/_react["default"].createElement(PlaceholderIcon, null));
299
+ };
300
+ var releaseBranch = (themeContext === null || themeContext === void 0 ? void 0 : themeContext.releaseBranch) || _releaseBranch["default"].release;
301
+ var appendedClassName = className + ' avoid-break';
302
+ var defaultImageOriginalUrl = _.get(defaultImage, 'url');
303
+ if (!defaultImageOriginalUrl && (!imageSet || imageSet.length === 0)) {
304
+ return /*#__PURE__*/_react["default"].createElement(ImgContainer, {
305
+ className: appendedClassName,
306
+ $heightString: "height: 100%;"
307
+ }, renderImagePlaceholder());
308
+ }
309
+ var srcset = (0, _image.getSrcsetString)(imageSet);
310
+ var isObjectFit = Boolean(objectFit);
311
+ var heightWidthRatio = _.get(defaultImage, 'height') / _.get(defaultImage, 'width');
312
+ if (isObjectFit && !heightWidthRatio) {
313
+ console.warn('Warning on Img component:', 'The `objecFit` is set, but no valid height/width ratio of `props.defaultImage` is given.', '`props.defaultImage`:', defaultImage);
314
+ }
315
+ var defaultImageSrc = (0, _storageUrlProcessor.replaceGCSUrlOrigin)(_.get(defaultImage, 'url'));
316
+ return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement(ImgContainer, {
317
+ className: appendedClassName,
318
+ $heightString: isObjectFit ? "height: 100%;" : "padding-top: ".concat(heightWidthRatio * 100, "%;"),
319
+ onClick: clickable ? openFullScreen : undefined,
320
+ $clickable: clickable
321
+ }, renderImagePlaceholder(), /*#__PURE__*/_react["default"].createElement(ImgBox, {
322
+ $toShow: isLoaded
323
+ }, isObjectFit ? /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement(ImgWithObjectFit, _extends({
324
+ alt: alt,
325
+ $objectFit: objectFit,
326
+ $objectPosition: objectPosition,
327
+ onLoad: handleImageLoaded,
328
+ ref: imgRef,
329
+ sizes: supportObjectFit ? sizes : '',
330
+ src: defaultImageSrc,
331
+ srcSet: supportObjectFit ? srcset : '',
332
+ hide: !supportObjectFit
333
+ }, imgProps)), supportObjectFit ? null : /*#__PURE__*/_react["default"].createElement(FallbackObjectFitImg, {
334
+ $url: _.get(defaultImage, 'url'),
335
+ $objectFit: objectFit,
336
+ $objectPosition: objectPosition
337
+ })) : /*#__PURE__*/_react["default"].createElement("img", _extends({
338
+ alt: alt,
339
+ onLoad: handleImageLoaded,
340
+ ref: imgRef,
341
+ sizes: sizes,
342
+ src: defaultImageSrc,
343
+ srcSet: srcset
344
+ }, imgProps)))), showFullScreenImg && /*#__PURE__*/_react["default"].createElement(_rwd.DesktopAndAbove, null, /*#__PURE__*/_react["default"].createElement(FullScreenImageMask, {
345
+ onClick: closeFullScreen
346
+ }, /*#__PURE__*/_react["default"].createElement(FullScreenImage, null, /*#__PURE__*/_react["default"].createElement("img", {
347
+ alt: alt,
348
+ ref: fullScreenImageRef,
349
+ sizes: sizes,
350
+ src: defaultImageSrc,
351
+ srcSet: srcset
352
+ }), /*#__PURE__*/_react["default"].createElement(CrossIcon, {
353
+ $crossIconPos: crossIconPos
354
+ }, /*#__PURE__*/_react["default"].createElement(_icon.Cross, {
355
+ releaseBranch: releaseBranch
356
+ }))))));
357
+ };
358
+ Img.propTypes = {
320
359
  alt: _propTypes["default"].string,
321
360
  className: _propTypes["default"].string,
322
361
  defaultImage: _imgWithPlaceholder["default"].imagePropType,
323
- // If the default image is not provided, this component will take the first item in `imageSet` as the default image.
324
- // The usage of default image:
325
- // 1. `img.src = defaultImage.url` for the browser not supporting `srcset`.
326
- // 2. The height/width ratio of the default image is used for this component. (no matter which candidate is acturally rendered)
327
362
  imgPlaceholderSrc: _propTypes["default"].string,
328
363
  placeholderNoBlur: _propTypes["default"].bool,
329
364
  noImgPlaceholder: _propTypes["default"].bool,
330
365
  imgProps: _propTypes["default"].object,
331
- // The properties of `imgProps` will all be passed to `<img />` element.
332
366
  imageSet: _propTypes["default"].arrayOf(_imgWithPlaceholder["default"].imagePropType),
333
367
  objectFit: _propTypes["default"].oneOf([objectFitConsts.cover, objectFitConsts.contain]),
334
368
  objectPosition: _propTypes["default"].string,
335
369
  sizes: _propTypes["default"].string.isRequired,
336
370
  clickable: _propTypes["default"].bool
337
- });
338
- _defineProperty(Img, "defaultProps", {
339
- alt: '',
340
- className: '',
341
- defaultImage: {},
342
- imageSet: [],
343
- imgPlaceholderSrc: '',
344
- imgProps: {},
345
- placeholderNoBlur: false,
346
- noImgPlaceholder: false,
347
- sizes: '',
348
- clickable: false
349
- });
371
+ };
372
+ var _default = exports["default"] = Img;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twreporter/react-article-components",
3
- "version": "2.2.2-rc.0",
3
+ "version": "2.3.0-rc.1",
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",
@@ -41,5 +41,5 @@
41
41
  "files": [
42
42
  "lib"
43
43
  ],
44
- "gitHead": "5a7ec087b2ed701763f6f4ea37553c90643c4e28"
44
+ "gitHead": "d0b553e3d3df415f0be4bcac782669612828f225"
45
45
  }