@twreporter/react-article-components 2.3.0-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 +17 -0
- package/lib/components/img-with-placeholder/index.js +246 -223
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,23 @@
|
|
|
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
|
+
|
|
6
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)
|
|
7
24
|
|
|
8
25
|
|
|
@@ -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 =
|
|
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
|
|
28
|
-
function
|
|
29
|
-
function
|
|
30
|
-
function
|
|
31
|
-
function
|
|
32
|
-
function
|
|
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:
|
|
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;
|
|
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 =
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
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
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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
|
-
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
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
|
-
}
|
|
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
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
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
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
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
|
-
|
|
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.3.0-rc.
|
|
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": "
|
|
44
|
+
"gitHead": "d0b553e3d3df415f0be4bcac782669612828f225"
|
|
45
45
|
}
|