@arcblock/ux 2.4.3 → 2.4.4
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/lib/Screenshot/BaseScreenshot/index.js +84 -0
- package/lib/Screenshot/BaseScreenshot/shells/Phone.js +57 -0
- package/lib/Screenshot/index.js +120 -6
- package/package.json +4 -4
- package/src/Screenshot/BaseScreenshot/index.jsx +77 -0
- package/src/Screenshot/BaseScreenshot/shells/Phone.jsx +33 -0
- package/src/Screenshot/index.js +97 -5
@@ -0,0 +1,84 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
4
|
+
value: true
|
5
|
+
});
|
6
|
+
exports.default = void 0;
|
7
|
+
|
8
|
+
var _Theme = require("@arcblock/ux/lib/Theme");
|
9
|
+
|
10
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
11
|
+
|
12
|
+
var _Phone = _interopRequireDefault(require("./shells/Phone"));
|
13
|
+
|
14
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
15
|
+
|
16
|
+
var _templateObject;
|
17
|
+
|
18
|
+
const _excluded = ["width", "children", "type", "sx"];
|
19
|
+
|
20
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
21
|
+
|
22
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
23
|
+
|
24
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
25
|
+
|
26
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
27
|
+
|
28
|
+
function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
|
29
|
+
|
30
|
+
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
31
|
+
|
32
|
+
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
33
|
+
|
34
|
+
const map = {
|
35
|
+
phone: _Phone.default
|
36
|
+
};
|
37
|
+
|
38
|
+
function Screenshot(_ref) {
|
39
|
+
let {
|
40
|
+
width,
|
41
|
+
children,
|
42
|
+
type,
|
43
|
+
sx
|
44
|
+
} = _ref,
|
45
|
+
rest = _objectWithoutProperties(_ref, _excluded);
|
46
|
+
|
47
|
+
const _type = type.toLowerCase();
|
48
|
+
|
49
|
+
const {
|
50
|
+
Shell,
|
51
|
+
ratio,
|
52
|
+
screenData,
|
53
|
+
width: defaultWidth
|
54
|
+
} = map[_type || 'phone'];
|
55
|
+
const Root = (0, _Theme.styled)('div')(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n position: relative;\n display: inline-block;\n width: ", ";\n &:after {\n display: block;\n content: '';\n padding-bottom: ", "%;\n }\n > svg {\n display: block;\n }\n\n .screenshot--container {\n position: absolute;\n left: ", "%;\n top: ", "%;\n width: ", "%;\n height: ", "%;\n ", ";\n background-color: #fff;\n overflow: hidden;\n > img {\n display: block;\n width: 100%;\n height: 100%;\n min-width: 100%;\n min-height: 100%;\n }\n }\n\n .absolute-size {\n position: absolute;\n left: 0;\n top: 0;\n width: 100%;\n height: 100%;\n }\n "])), width || "".concat(defaultWidth, "px"), ratio * 100, screenData.x * 100, screenData.y * 100, screenData.width * 100, screenData.height * 100, screenData.radius ? "border-radius: ".concat(screenData.radius) : '');
|
56
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
57
|
+
style: {
|
58
|
+
display: 'flex',
|
59
|
+
justifyContent: 'center'
|
60
|
+
},
|
61
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(Root, _objectSpread(_objectSpread({}, rest), {}, {
|
62
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(Shell, {
|
63
|
+
className: "absolute-size"
|
64
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
65
|
+
className: "screenshot--container",
|
66
|
+
children: children
|
67
|
+
})]
|
68
|
+
}))
|
69
|
+
});
|
70
|
+
}
|
71
|
+
|
72
|
+
Screenshot.propTypes = {
|
73
|
+
width: _propTypes.default.number,
|
74
|
+
type: _propTypes.default.string,
|
75
|
+
children: _propTypes.default.node.isRequired,
|
76
|
+
sx: _propTypes.default.object
|
77
|
+
};
|
78
|
+
Screenshot.defaultProps = {
|
79
|
+
width: 0,
|
80
|
+
type: 'phone',
|
81
|
+
sx: {}
|
82
|
+
};
|
83
|
+
var _default = Screenshot;
|
84
|
+
exports.default = _default;
|
@@ -0,0 +1,57 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
4
|
+
value: true
|
5
|
+
});
|
6
|
+
exports.Shell = Shell;
|
7
|
+
exports.width = exports.screenData = exports.ratio = exports.height = exports.default = void 0;
|
8
|
+
|
9
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
10
|
+
|
11
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
12
|
+
|
13
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
14
|
+
|
15
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
16
|
+
|
17
|
+
const width = 268;
|
18
|
+
exports.width = width;
|
19
|
+
const height = 554;
|
20
|
+
exports.height = height;
|
21
|
+
|
22
|
+
function Shell(_ref) {
|
23
|
+
let rest = Object.assign({}, _ref);
|
24
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)("svg", _objectSpread(_objectSpread({
|
25
|
+
width: "268",
|
26
|
+
height: "554",
|
27
|
+
viewBox: "0 0 268 554",
|
28
|
+
fill: "none",
|
29
|
+
xmlns: "http://www.w3.org/2000/svg"
|
30
|
+
}, rest), {}, {
|
31
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
|
32
|
+
d: "M37 7.5H230.929C247.222 7.5 260.429 20.7076 260.429 37V517C260.429 533.292 247.222 546.5 230.929 546.5H37C20.7076 546.5 7.5 533.292 7.5 517V37C7.5 20.7076 20.7076 7.5 37 7.5Z",
|
33
|
+
fill: "#2F2F2F",
|
34
|
+
stroke: "#2F2F2F",
|
35
|
+
strokeWidth: "15"
|
36
|
+
})
|
37
|
+
}));
|
38
|
+
}
|
39
|
+
|
40
|
+
const ratio = 798 / 386;
|
41
|
+
exports.ratio = ratio;
|
42
|
+
const screenData = {
|
43
|
+
x: 15 / 384,
|
44
|
+
y: 15 / 794,
|
45
|
+
width: 354 / 384,
|
46
|
+
height: 764 / 794,
|
47
|
+
radius: '10% / 5%'
|
48
|
+
};
|
49
|
+
exports.screenData = screenData;
|
50
|
+
var _default = {
|
51
|
+
Shell,
|
52
|
+
ratio,
|
53
|
+
screenData,
|
54
|
+
width,
|
55
|
+
height
|
56
|
+
};
|
57
|
+
exports.default = _default;
|
package/lib/Screenshot/index.js
CHANGED
@@ -13,13 +13,16 @@ var _Util = require("../Util");
|
|
13
13
|
|
14
14
|
var _Theme = require("../Theme");
|
15
15
|
|
16
|
+
var _BaseScreenshot = _interopRequireDefault(require("./BaseScreenshot"));
|
17
|
+
|
16
18
|
require("./devices.css");
|
17
19
|
|
18
20
|
var _jsxRuntime = require("react/jsx-runtime");
|
19
21
|
|
20
|
-
var _templateObject;
|
22
|
+
var _templateObject, _templateObject2;
|
21
23
|
|
22
|
-
const _excluded = ["type", "children", "style", "className", "width", "height"]
|
24
|
+
const _excluded = ["type", "children", "style", "className", "width", "height"],
|
25
|
+
_excluded2 = ["type", "src", "children", "style", "sx"];
|
23
26
|
|
24
27
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
25
28
|
|
@@ -143,8 +146,8 @@ const findChildren = function findChildren(children) {
|
|
143
146
|
// If neither of them are found, the whole child tree is rendered
|
144
147
|
|
145
148
|
|
146
|
-
function
|
147
|
-
const newProps = (0, _Util.mergeProps)(props,
|
149
|
+
function OldScreenshot(props) {
|
150
|
+
const newProps = (0, _Util.mergeProps)(props, OldScreenshot, ['style', 'width', 'height']);
|
148
151
|
|
149
152
|
const {
|
150
153
|
type,
|
@@ -189,7 +192,7 @@ function Screenshot(props) {
|
|
189
192
|
}
|
190
193
|
|
191
194
|
const Div = (0, _Theme.styled)('div')(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n @media (max-width: ", "px) {\n transform-origin: 0 0;\n transform: scale(", ");\n }\n .device-content {\n overflow: hidden;\n }\n .device-content video,\n .device-content img {\n border-radius: ", "px;\n background-color: #fff;\n background-position: center center;\n background-size: cover;\n object-fit: cover;\n width: 100.1%;\n height: 100.1%;\n }\n"])), props => types[props.type].width, props => types[props.type].scale, props => props.contentRadius);
|
192
|
-
|
195
|
+
OldScreenshot.propTypes = {
|
193
196
|
type: _propTypes.default.oneOf(Object.keys(types)),
|
194
197
|
children: _propTypes.default.any.isRequired,
|
195
198
|
className: _propTypes.default.string,
|
@@ -197,12 +200,123 @@ Screenshot.propTypes = {
|
|
197
200
|
height: _propTypes.default.number,
|
198
201
|
style: _propTypes.default.oneOfType([_propTypes.default.object, _propTypes.default.string])
|
199
202
|
};
|
200
|
-
|
203
|
+
OldScreenshot.defaultProps = {
|
201
204
|
type: 'iphone-x',
|
202
205
|
className: '',
|
203
206
|
style: '{}',
|
204
207
|
width: 0,
|
205
208
|
height: 0
|
206
209
|
};
|
210
|
+
/**
|
211
|
+
* 用于修正旧版 Screenshot 无法匹配尺寸的问题
|
212
|
+
* @param {*} props params to OldScreenshot
|
213
|
+
* @returns <OldScreenshot />
|
214
|
+
*/
|
215
|
+
|
216
|
+
function ScreenFixer(props) {
|
217
|
+
const screenEl = (0, _react.useRef)(null);
|
218
|
+
const [height, setHeight] = (0, _react.useState)(undefined);
|
219
|
+
const [scale, setScale] = (0, _react.useState)(null);
|
220
|
+
(0, _react.useEffect)(() => {
|
221
|
+
let resizeObs;
|
222
|
+
|
223
|
+
const fixSize = () => {
|
224
|
+
const {
|
225
|
+
clientWidth
|
226
|
+
} = screenEl.current; // 获取内部元素的宽高
|
227
|
+
|
228
|
+
const {
|
229
|
+
clientWidth: targetWidth,
|
230
|
+
clientHeight: targetHeight
|
231
|
+
} = screenEl.current.children[0];
|
232
|
+
const realScale = clientWidth / targetWidth;
|
233
|
+
|
234
|
+
if (realScale < 1) {
|
235
|
+
setScale(realScale);
|
236
|
+
setHeight(realScale * targetHeight);
|
237
|
+
} else {
|
238
|
+
setScale(null);
|
239
|
+
setHeight(undefined);
|
240
|
+
}
|
241
|
+
};
|
242
|
+
|
243
|
+
if (screenEl.current) {
|
244
|
+
resizeObs = new ResizeObserver(fixSize);
|
245
|
+
resizeObs.observe(screenEl.current);
|
246
|
+
}
|
247
|
+
|
248
|
+
return () => {
|
249
|
+
if (resizeObs) {
|
250
|
+
resizeObs.disconnect();
|
251
|
+
}
|
252
|
+
}; // eslint-disable-next-line react-hooks/exhaustive-deps
|
253
|
+
}, [screenEl.current]);
|
254
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(ReScreen, {
|
255
|
+
ref: screenEl,
|
256
|
+
style: {
|
257
|
+
height
|
258
|
+
},
|
259
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(OldScreenshot, _objectSpread(_objectSpread({}, props), {}, {
|
260
|
+
style: {
|
261
|
+
transform: scale ? "scale(".concat(scale, ")") : undefined
|
262
|
+
}
|
263
|
+
}))
|
264
|
+
});
|
265
|
+
}
|
266
|
+
|
267
|
+
const ReScreen = (0, _Theme.styled)('div')(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n div[type] {\n transform: scale(1);\n transform-origin: 0 0;\n }\n"])));
|
268
|
+
|
269
|
+
function Screenshot(_ref) {
|
270
|
+
let {
|
271
|
+
type,
|
272
|
+
src,
|
273
|
+
children,
|
274
|
+
style,
|
275
|
+
sx
|
276
|
+
} = _ref,
|
277
|
+
rest = _objectWithoutProperties(_ref, _excluded2);
|
278
|
+
|
279
|
+
const _type = type.toLowerCase(); // 新版采用容器采用BaseScreenshot,svg集成,更容易拓展,响应式更好
|
280
|
+
|
281
|
+
|
282
|
+
if (['phone'].includes(_type)) {
|
283
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_BaseScreenshot.default, _objectSpread(_objectSpread({
|
284
|
+
type: _type,
|
285
|
+
sx: _objectSpread(_objectSpread({}, sx), style)
|
286
|
+
}, rest), {}, {
|
287
|
+
children: children || (src ? /*#__PURE__*/(0, _jsxRuntime.jsx)("img", {
|
288
|
+
src: src,
|
289
|
+
alt: "screenshot"
|
290
|
+
}) : null)
|
291
|
+
}));
|
292
|
+
} // 旧版采用纯css制作,定制性欠缺,暂时保留使用
|
293
|
+
|
294
|
+
|
295
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(ScreenFixer, _objectSpread(_objectSpread({
|
296
|
+
type: type
|
297
|
+
}, rest), {}, {
|
298
|
+
sx: _objectSpread(_objectSpread(_objectSpread({}, sx), style), {}, {
|
299
|
+
margin: 'auto'
|
300
|
+
}),
|
301
|
+
children: children || (src ? /*#__PURE__*/(0, _jsxRuntime.jsx)("img", {
|
302
|
+
src: src,
|
303
|
+
alt: "screenshot"
|
304
|
+
}) : null)
|
305
|
+
}));
|
306
|
+
}
|
307
|
+
|
308
|
+
Screenshot.propTypes = {
|
309
|
+
type: _propTypes.default.string.isRequired,
|
310
|
+
src: _propTypes.default.string,
|
311
|
+
style: _propTypes.default.object,
|
312
|
+
sx: _propTypes.default.object,
|
313
|
+
children: _propTypes.default.any
|
314
|
+
};
|
315
|
+
Screenshot.defaultProps = {
|
316
|
+
src: '',
|
317
|
+
children: null,
|
318
|
+
style: {},
|
319
|
+
sx: {}
|
320
|
+
};
|
207
321
|
var _default = Screenshot;
|
208
322
|
exports.default = _default;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@arcblock/ux",
|
3
|
-
"version": "2.4.
|
3
|
+
"version": "2.4.4",
|
4
4
|
"description": "Common used react components for arcblock products",
|
5
5
|
"keywords": [
|
6
6
|
"react",
|
@@ -47,10 +47,10 @@
|
|
47
47
|
"react": ">=18.1.0",
|
48
48
|
"react-ga": "^2.7.0"
|
49
49
|
},
|
50
|
-
"gitHead": "
|
50
|
+
"gitHead": "655d38787fa04e77a719601a46b93d49cde243e4",
|
51
51
|
"dependencies": {
|
52
|
-
"@arcblock/icons": "^2.4.
|
53
|
-
"@arcblock/react-hooks": "^2.4.
|
52
|
+
"@arcblock/icons": "^2.4.4",
|
53
|
+
"@arcblock/react-hooks": "^2.4.4",
|
54
54
|
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
55
55
|
"@emotion/react": "^11.10.0",
|
56
56
|
"@emotion/styled": "^11.10.0",
|
@@ -0,0 +1,77 @@
|
|
1
|
+
import { styled } from '@arcblock/ux/lib/Theme';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
|
4
|
+
import phone from './shells/Phone';
|
5
|
+
|
6
|
+
const map = {
|
7
|
+
phone,
|
8
|
+
};
|
9
|
+
|
10
|
+
function Screenshot({ width, children, type, sx, ...rest }) {
|
11
|
+
const _type = type.toLowerCase();
|
12
|
+
|
13
|
+
const { Shell, ratio, screenData, width: defaultWidth } = map[_type || 'phone'];
|
14
|
+
|
15
|
+
const Root = styled('div')`
|
16
|
+
position: relative;
|
17
|
+
display: inline-block;
|
18
|
+
width: ${width || `${defaultWidth}px`};
|
19
|
+
&:after {
|
20
|
+
display: block;
|
21
|
+
content: '';
|
22
|
+
padding-bottom: ${ratio * 100}%;
|
23
|
+
}
|
24
|
+
> svg {
|
25
|
+
display: block;
|
26
|
+
}
|
27
|
+
|
28
|
+
.screenshot--container {
|
29
|
+
position: absolute;
|
30
|
+
left: ${screenData.x * 100}%;
|
31
|
+
top: ${screenData.y * 100}%;
|
32
|
+
width: ${screenData.width * 100}%;
|
33
|
+
height: ${screenData.height * 100}%;
|
34
|
+
${screenData.radius ? `border-radius: ${screenData.radius}` : ''};
|
35
|
+
background-color: #fff;
|
36
|
+
overflow: hidden;
|
37
|
+
> img {
|
38
|
+
display: block;
|
39
|
+
width: 100%;
|
40
|
+
height: 100%;
|
41
|
+
min-width: 100%;
|
42
|
+
min-height: 100%;
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
.absolute-size {
|
47
|
+
position: absolute;
|
48
|
+
left: 0;
|
49
|
+
top: 0;
|
50
|
+
width: 100%;
|
51
|
+
height: 100%;
|
52
|
+
}
|
53
|
+
`;
|
54
|
+
|
55
|
+
return (
|
56
|
+
<div style={{ display: 'flex', justifyContent: 'center' }}>
|
57
|
+
<Root {...rest}>
|
58
|
+
<Shell className="absolute-size" />
|
59
|
+
<div className="screenshot--container">{children}</div>
|
60
|
+
</Root>
|
61
|
+
</div>
|
62
|
+
);
|
63
|
+
}
|
64
|
+
|
65
|
+
Screenshot.propTypes = {
|
66
|
+
width: PropTypes.number,
|
67
|
+
type: PropTypes.string,
|
68
|
+
children: PropTypes.node.isRequired,
|
69
|
+
sx: PropTypes.object,
|
70
|
+
};
|
71
|
+
Screenshot.defaultProps = {
|
72
|
+
width: 0,
|
73
|
+
type: 'phone',
|
74
|
+
sx: {},
|
75
|
+
};
|
76
|
+
|
77
|
+
export default Screenshot;
|
@@ -0,0 +1,33 @@
|
|
1
|
+
export const width = 268;
|
2
|
+
export const height = 554;
|
3
|
+
|
4
|
+
export function Shell({ ...rest }) {
|
5
|
+
return (
|
6
|
+
<svg width="268" height="554" viewBox="0 0 268 554" fill="none" xmlns="http://www.w3.org/2000/svg" {...rest}>
|
7
|
+
<path
|
8
|
+
d="M37 7.5H230.929C247.222 7.5 260.429 20.7076 260.429 37V517C260.429 533.292 247.222 546.5 230.929 546.5H37C20.7076 546.5 7.5 533.292 7.5 517V37C7.5 20.7076 20.7076 7.5 37 7.5Z"
|
9
|
+
fill="#2F2F2F"
|
10
|
+
stroke="#2F2F2F"
|
11
|
+
strokeWidth="15"
|
12
|
+
/>
|
13
|
+
</svg>
|
14
|
+
);
|
15
|
+
}
|
16
|
+
|
17
|
+
export const ratio = 798 / 386;
|
18
|
+
|
19
|
+
export const screenData = {
|
20
|
+
x: 15 / 384,
|
21
|
+
y: 15 / 794,
|
22
|
+
width: 354 / 384,
|
23
|
+
height: 764 / 794,
|
24
|
+
radius: '10% / 5%',
|
25
|
+
};
|
26
|
+
|
27
|
+
export default {
|
28
|
+
Shell,
|
29
|
+
ratio,
|
30
|
+
screenData,
|
31
|
+
width,
|
32
|
+
height,
|
33
|
+
};
|
package/src/Screenshot/index.js
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
import { createElement, Children, cloneElement } from 'react';
|
1
|
+
import { createElement, Children, cloneElement, useEffect, useRef, useState } from 'react';
|
2
2
|
import PropTypes from 'prop-types';
|
3
3
|
|
4
4
|
import { mergeProps } from '../Util';
|
5
5
|
import { styled } from '../Theme';
|
6
|
+
import BaseScreenshot from './BaseScreenshot';
|
6
7
|
|
7
8
|
import './devices.css';
|
8
9
|
|
@@ -116,8 +117,8 @@ const findChildren = (children, returnArgWhenNotFound = true) => {
|
|
116
117
|
// This component is built upon the awesome device.css lib
|
117
118
|
// By default it will find and only render img/video tags in the children
|
118
119
|
// If neither of them are found, the whole child tree is rendered
|
119
|
-
function
|
120
|
-
const newProps = mergeProps(props,
|
120
|
+
function OldScreenshot(props) {
|
121
|
+
const newProps = mergeProps(props, OldScreenshot, ['style', 'width', 'height']);
|
121
122
|
const { type, children, style, className, width, height, ...rest } = newProps;
|
122
123
|
const { zIndex = 0, borderRadius = 0 } = types[type] || {};
|
123
124
|
|
@@ -164,7 +165,7 @@ const Div = styled('div')`
|
|
164
165
|
}
|
165
166
|
`;
|
166
167
|
|
167
|
-
|
168
|
+
OldScreenshot.propTypes = {
|
168
169
|
type: PropTypes.oneOf(Object.keys(types)),
|
169
170
|
children: PropTypes.any.isRequired,
|
170
171
|
className: PropTypes.string,
|
@@ -173,7 +174,7 @@ Screenshot.propTypes = {
|
|
173
174
|
style: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
|
174
175
|
};
|
175
176
|
|
176
|
-
|
177
|
+
OldScreenshot.defaultProps = {
|
177
178
|
type: 'iphone-x',
|
178
179
|
className: '',
|
179
180
|
style: '{}',
|
@@ -181,4 +182,95 @@ Screenshot.defaultProps = {
|
|
181
182
|
height: 0,
|
182
183
|
};
|
183
184
|
|
185
|
+
/**
|
186
|
+
* 用于修正旧版 Screenshot 无法匹配尺寸的问题
|
187
|
+
* @param {*} props params to OldScreenshot
|
188
|
+
* @returns <OldScreenshot />
|
189
|
+
*/
|
190
|
+
function ScreenFixer(props) {
|
191
|
+
const screenEl = useRef(null);
|
192
|
+
const [height, setHeight] = useState(undefined);
|
193
|
+
const [scale, setScale] = useState(null);
|
194
|
+
|
195
|
+
useEffect(() => {
|
196
|
+
let resizeObs;
|
197
|
+
|
198
|
+
const fixSize = () => {
|
199
|
+
const { clientWidth } = screenEl.current;
|
200
|
+
|
201
|
+
// 获取内部元素的宽高
|
202
|
+
const { clientWidth: targetWidth, clientHeight: targetHeight } = screenEl.current.children[0];
|
203
|
+
|
204
|
+
const realScale = clientWidth / targetWidth;
|
205
|
+
if (realScale < 1) {
|
206
|
+
setScale(realScale);
|
207
|
+
setHeight(realScale * targetHeight);
|
208
|
+
} else {
|
209
|
+
setScale(null);
|
210
|
+
setHeight(undefined);
|
211
|
+
}
|
212
|
+
};
|
213
|
+
|
214
|
+
if (screenEl.current) {
|
215
|
+
resizeObs = new ResizeObserver(fixSize);
|
216
|
+
resizeObs.observe(screenEl.current);
|
217
|
+
}
|
218
|
+
|
219
|
+
return () => {
|
220
|
+
if (resizeObs) {
|
221
|
+
resizeObs.disconnect();
|
222
|
+
}
|
223
|
+
};
|
224
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
225
|
+
}, [screenEl.current]);
|
226
|
+
|
227
|
+
return (
|
228
|
+
<ReScreen ref={screenEl} style={{ height }}>
|
229
|
+
<OldScreenshot {...props} style={{ transform: scale ? `scale(${scale})` : undefined }} />
|
230
|
+
</ReScreen>
|
231
|
+
);
|
232
|
+
}
|
233
|
+
|
234
|
+
const ReScreen = styled('div')`
|
235
|
+
div[type] {
|
236
|
+
transform: scale(1);
|
237
|
+
transform-origin: 0 0;
|
238
|
+
}
|
239
|
+
`;
|
240
|
+
|
241
|
+
function Screenshot({ type, src, children, style, sx, ...rest }) {
|
242
|
+
const _type = type.toLowerCase();
|
243
|
+
|
244
|
+
// 新版采用容器采用BaseScreenshot,svg集成,更容易拓展,响应式更好
|
245
|
+
if (['phone'].includes(_type)) {
|
246
|
+
return (
|
247
|
+
<BaseScreenshot type={_type} sx={{ ...sx, ...style }} {...rest}>
|
248
|
+
{children || (src ? <img src={src} alt="screenshot" /> : null)}
|
249
|
+
</BaseScreenshot>
|
250
|
+
);
|
251
|
+
}
|
252
|
+
|
253
|
+
// 旧版采用纯css制作,定制性欠缺,暂时保留使用
|
254
|
+
return (
|
255
|
+
<ScreenFixer type={type} {...rest} sx={{ ...sx, ...style, margin: 'auto' }}>
|
256
|
+
{children || (src ? <img src={src} alt="screenshot" /> : null)}
|
257
|
+
</ScreenFixer>
|
258
|
+
);
|
259
|
+
}
|
260
|
+
|
261
|
+
Screenshot.propTypes = {
|
262
|
+
type: PropTypes.string.isRequired,
|
263
|
+
src: PropTypes.string,
|
264
|
+
style: PropTypes.object,
|
265
|
+
sx: PropTypes.object,
|
266
|
+
children: PropTypes.any,
|
267
|
+
};
|
268
|
+
|
269
|
+
Screenshot.defaultProps = {
|
270
|
+
src: '',
|
271
|
+
children: null,
|
272
|
+
style: {},
|
273
|
+
sx: {},
|
274
|
+
};
|
275
|
+
|
184
276
|
export default Screenshot;
|