sanity-plugin-iframe-pane 1.1.3 → 1.1.5
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/.releaserc.json +7 -0
- package/.semantic-release/sanity-plugin-iframe-pane-1.1.5.tgz +0 -0
- package/CHANGELOG.md +12 -0
- package/LICENSE +1 -1
- package/README.md +17 -4
- package/lib/Iframe.js +28 -52
- package/lib/Iframe.js.map +1 -1
- package/lib/hooks/useCopytoClipboard.js +6 -20
- package/lib/hooks/useCopytoClipboard.js.map +1 -1
- package/package.json +18 -15
- package/src/Iframe.tsx +7 -1
package/.releaserc.json
ADDED
|
Binary file
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!-- markdownlint-disable --><!-- textlint-disable -->
|
|
2
|
+
|
|
3
|
+
# 📓 Changelog
|
|
4
|
+
|
|
5
|
+
All notable changes to this project will be documented in this file. See
|
|
6
|
+
[Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
7
|
+
|
|
8
|
+
## [1.1.5](https://github.com/sanity-io/sanity-plugin-iframe-pane/compare/v1.1.4...v1.1.5) (2022-11-22)
|
|
9
|
+
|
|
10
|
+
### Bug Fixes
|
|
11
|
+
|
|
12
|
+
- **ci:** publish using semantic-release ([11c1fea](https://github.com/sanity-io/sanity-plugin-iframe-pane/commit/11c1fea95cd936198599d12f459a695241ba792f))
|
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
# sanity-plugin-iframe-pane
|
|
2
2
|
|
|
3
|
-
>
|
|
4
|
-
>
|
|
5
|
-
> There is a [Studio v3 specific version in the studio-v3 branch](https://github.com/SimeonGriggs/sanity-plugin-iframe-pane/tree/studio-v3)
|
|
3
|
+
> This is a **Sanity Studio v2** plugin.
|
|
4
|
+
> There is a [Studio v3 specific version](https://github.com/sanity-io/sanity-plugin-iframe-pane)
|
|
6
5
|
|
|
7
6
|
Display any URL in a View Pane, along with helpful buttons to Copy the URL or open in a new tab.
|
|
8
7
|
|
|
@@ -12,8 +11,15 @@ Accepts either a string or an async function to resolve a URL based on the curre
|
|
|
12
11
|
|
|
13
12
|
## Installation
|
|
14
13
|
|
|
14
|
+
```sh
|
|
15
|
+
yarn add sanity-plugin-iframe-pane@studio-v2
|
|
15
16
|
```
|
|
16
|
-
|
|
17
|
+
|
|
18
|
+
Next, add `"iframe-pane"` to `sanity.json` plugins array:
|
|
19
|
+
```json
|
|
20
|
+
"plugins": [
|
|
21
|
+
"iframe-pane"
|
|
22
|
+
]
|
|
17
23
|
```
|
|
18
24
|
|
|
19
25
|
This is designed to be used as a [Component inside of a View](https://www.sanity.io/docs/structure-builder-reference#c0c8284844b7).
|
|
@@ -38,6 +44,13 @@ S.view
|
|
|
38
44
|
button: true, // default `undefined`
|
|
39
45
|
revision: true, // boolean | number. default `undefined`. If a number is provided, add a delay (in ms) before the automatic reload on document revision
|
|
40
46
|
},
|
|
47
|
+
// Optional: Pass attributes to the underlying `iframe` element:
|
|
48
|
+
// See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe
|
|
49
|
+
attributes: {
|
|
50
|
+
allow: 'fullscreen' // string, optional
|
|
51
|
+
referrerPolicy: 'strict-origin-when-cross-origin' // string, optional
|
|
52
|
+
sandbox: 'allow-same-origin' // string, optional
|
|
53
|
+
}
|
|
41
54
|
})
|
|
42
55
|
.title("Preview");
|
|
43
56
|
```
|
package/lib/Iframe.js
CHANGED
|
@@ -4,37 +4,22 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
var _react = _interopRequireWildcard(require("react"));
|
|
9
|
-
|
|
10
8
|
var _ui = require("@sanity/ui");
|
|
11
|
-
|
|
12
9
|
var _icons = require("@sanity/icons");
|
|
13
|
-
|
|
14
10
|
var _useCopytoClipboard = _interopRequireDefault(require("./hooks/useCopytoClipboard"));
|
|
15
|
-
|
|
16
11
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
|
-
|
|
18
12
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
19
|
-
|
|
20
13
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
21
|
-
|
|
14
|
+
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); }
|
|
22
15
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
23
|
-
|
|
24
16
|
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
25
|
-
|
|
26
17
|
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
27
|
-
|
|
28
18
|
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
|
-
|
|
30
19
|
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); }
|
|
31
|
-
|
|
32
20
|
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; }
|
|
33
|
-
|
|
34
21
|
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
35
|
-
|
|
36
22
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
37
|
-
|
|
38
23
|
var sizes = {
|
|
39
24
|
desktop: {
|
|
40
25
|
backgroundColor: "white",
|
|
@@ -49,80 +34,73 @@ var sizes = {
|
|
|
49
34
|
maxHeight: 736
|
|
50
35
|
}
|
|
51
36
|
};
|
|
52
|
-
|
|
53
37
|
function Iframe(props) {
|
|
54
38
|
var sanityDocument = props.document,
|
|
55
|
-
|
|
39
|
+
options = props.options;
|
|
56
40
|
var url = options.url,
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
41
|
+
_options$defaultSize = options.defaultSize,
|
|
42
|
+
defaultSize = _options$defaultSize === void 0 ? "desktop" : _options$defaultSize,
|
|
43
|
+
reload = options.reload,
|
|
44
|
+
_options$attributes = options.attributes,
|
|
45
|
+
attributes = _options$attributes === void 0 ? {} : _options$attributes;
|
|
61
46
|
var _useState = (0, _react.useState)(typeof url === 'string' ? url : ""),
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
47
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
48
|
+
displayUrl = _useState2[0],
|
|
49
|
+
setDisplayUrl = _useState2[1];
|
|
66
50
|
var _useState3 = (0, _react.useState)(defaultSize),
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
51
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
52
|
+
iframeSize = _useState4[0],
|
|
53
|
+
setIframeSize = _useState4[1];
|
|
71
54
|
var input = (0, _react.useRef)();
|
|
72
55
|
var iframe = (0, _react.useRef)();
|
|
73
56
|
var displayed = sanityDocument.displayed;
|
|
74
|
-
|
|
75
57
|
var _useCopyToClipboard = (0, _useCopytoClipboard.default)(),
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
58
|
+
_useCopyToClipboard2 = _slicedToArray(_useCopyToClipboard, 2),
|
|
59
|
+
copy = _useCopyToClipboard2[1];
|
|
79
60
|
function handleCopy() {
|
|
80
61
|
var _input$current;
|
|
81
|
-
|
|
82
62
|
if (!(input !== null && input !== void 0 && (_input$current = input.current) !== null && _input$current !== void 0 && _input$current.value)) return;
|
|
83
63
|
copy(input.current.value);
|
|
84
64
|
}
|
|
85
|
-
|
|
86
65
|
function handleReload() {
|
|
87
66
|
if (!(iframe !== null && iframe !== void 0 && iframe.current)) {
|
|
88
67
|
return;
|
|
89
|
-
}
|
|
90
|
-
// eslint-disable-next-line no-self-assign
|
|
91
|
-
|
|
68
|
+
}
|
|
92
69
|
|
|
70
|
+
// Funky way to reload an iframe without CORS issuies
|
|
71
|
+
// eslint-disable-next-line no-self-assign
|
|
93
72
|
iframe.current.src = iframe.current.src;
|
|
94
|
-
}
|
|
95
|
-
|
|
73
|
+
}
|
|
96
74
|
|
|
75
|
+
// Reload on new revisions
|
|
97
76
|
(0, _react.useEffect)(() => {
|
|
98
77
|
if (reload !== null && reload !== void 0 && reload.revision || (reload === null || reload === void 0 ? void 0 : reload.revision) == 0) {
|
|
99
78
|
setTimeout(() => {
|
|
100
79
|
handleReload();
|
|
101
80
|
}, Number(reload === null || reload === void 0 ? void 0 : reload.revision));
|
|
102
81
|
}
|
|
103
|
-
}, [displayed._rev, reload === null || reload === void 0 ? void 0 : reload.revision]);
|
|
82
|
+
}, [displayed._rev, reload === null || reload === void 0 ? void 0 : reload.revision]);
|
|
104
83
|
|
|
84
|
+
// Set initial URL and refresh on new revisions
|
|
105
85
|
(0, _react.useEffect)(() => {
|
|
106
86
|
var getUrl = /*#__PURE__*/function () {
|
|
107
87
|
var _ref = _asyncToGenerator(function* () {
|
|
108
|
-
var resolveUrl = typeof url === 'function' ? yield url(displayed) : "";
|
|
88
|
+
var resolveUrl = typeof url === 'function' ? yield url(displayed) : "";
|
|
109
89
|
|
|
90
|
+
// Only update state if URL has changed
|
|
110
91
|
if (resolveUrl !== displayUrl) {
|
|
111
92
|
setDisplayUrl(resolveUrl);
|
|
112
93
|
}
|
|
113
94
|
});
|
|
114
|
-
|
|
115
95
|
return function getUrl() {
|
|
116
96
|
return _ref.apply(this, arguments);
|
|
117
97
|
};
|
|
118
98
|
}();
|
|
119
|
-
|
|
120
99
|
if (typeof url === 'function') {
|
|
121
100
|
getUrl();
|
|
122
|
-
}
|
|
123
|
-
|
|
101
|
+
}
|
|
102
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
124
103
|
}, [displayed._rev]);
|
|
125
|
-
|
|
126
104
|
if (!displayUrl || typeof displayUrl !== 'string') {
|
|
127
105
|
return /*#__PURE__*/_react.default.createElement(_ui.ThemeProvider, null, /*#__PURE__*/_react.default.createElement(_ui.Flex, {
|
|
128
106
|
padding: 5,
|
|
@@ -130,7 +108,6 @@ function Iframe(props) {
|
|
|
130
108
|
justify: "center"
|
|
131
109
|
}, /*#__PURE__*/_react.default.createElement(_ui.Spinner, null)));
|
|
132
110
|
}
|
|
133
|
-
|
|
134
111
|
return /*#__PURE__*/_react.default.createElement(_ui.ThemeProvider, null, /*#__PURE__*/_react.default.createElement("textarea", {
|
|
135
112
|
style: {
|
|
136
113
|
position: "absolute",
|
|
@@ -203,15 +180,14 @@ function Iframe(props) {
|
|
|
203
180
|
style: {
|
|
204
181
|
height: "100%"
|
|
205
182
|
}
|
|
206
|
-
}, /*#__PURE__*/_react.default.createElement("iframe", {
|
|
183
|
+
}, /*#__PURE__*/_react.default.createElement("iframe", _extends({
|
|
207
184
|
ref: iframe,
|
|
208
185
|
title: "preview",
|
|
209
186
|
style: sizes[iframeSize],
|
|
210
187
|
frameBorder: "0",
|
|
211
188
|
src: displayUrl
|
|
212
|
-
})))));
|
|
189
|
+
}, attributes))))));
|
|
213
190
|
}
|
|
214
|
-
|
|
215
191
|
var _default = Iframe;
|
|
216
192
|
exports.default = _default;
|
|
217
193
|
//# sourceMappingURL=Iframe.js.map
|
package/lib/Iframe.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Iframe.js","names":["sizes","desktop","backgroundColor","width","height","maxHeight","mobile","Iframe","props","sanityDocument","document","options","url","defaultSize","reload","useState","displayUrl","setDisplayUrl","iframeSize","setIframeSize","input","useRef","iframe","displayed","useCopyToClipboard","copy","handleCopy","current","value","handleReload","src","useEffect","revision","setTimeout","Number","_rev","getUrl","resolveUrl","position","pointerEvents","opacity","MobileDeviceIcon","button","UndoIcon","CopyIcon","LeaveIcon","window","open"],"sources":["../src/Iframe.tsx"],"sourcesContent":["import React, {useEffect, useState, useRef} from 'react'\nimport {SanityDocumentLike} from 'sanity'\nimport {Box, Flex, Text, Button, ThemeProvider, Card, Spinner} from '@sanity/ui'\nimport {UndoIcon, CopyIcon, LeaveIcon, MobileDeviceIcon} from '@sanity/icons'\n\nimport useCopyToClipboard from './hooks/useCopytoClipboard'\n\nconst sizes = {\n desktop: {backgroundColor: `white`, width: `100%`, height: `100%`, maxHeight: `100%`},\n mobile: {backgroundColor: `white`, width: 414, height: `100%`, maxHeight: 736},\n}\n\nexport type IframeOptions = {\n url: string | ((document: SanityDocumentLike) => unknown)\n defaultSize?: 'desktop' | 'mobile'\n reload: {\n revision: boolean | number\n button: boolean\n }\n}\n\nexport type IframeProps = {\n document: {\n displayed: SanityDocumentLike\n }\n options: IframeOptions\n}\n\nfunction Iframe(props: IframeProps) {\n const {document: sanityDocument, options} = props\n const {url, defaultSize = `desktop`, reload} = options\n const [displayUrl, setDisplayUrl] = useState(typeof url === 'string' ? url : ``)\n const [iframeSize, setIframeSize] = useState(defaultSize)\n const input = useRef()\n const iframe = useRef()\n const {displayed} = sanityDocument\n const [, copy] = useCopyToClipboard()\n\n function handleCopy() {\n if (!input?.current?.value) return\n\n copy(input.current.value)\n }\n\n function handleReload() {\n if (!iframe?.current) {\n return\n }\n\n // Funky way to reload an iframe without CORS issuies\n // eslint-disable-next-line no-self-assign\n iframe.current.src = iframe.current.src\n }\n\n // Reload on new revisions\n useEffect(() => {\n if (reload?.revision || reload?.revision == 0) {\n setTimeout(() => {\n handleReload()\n }, Number(reload?.revision))\n }\n }, [displayed._rev, reload?.revision])\n\n // Set initial URL and refresh on new revisions\n useEffect(() => {\n const getUrl = async () => {\n const resolveUrl = typeof url === 'function' ? await url(displayed) : ``\n\n // Only update state if URL has changed\n if (resolveUrl !== displayUrl) {\n setDisplayUrl(resolveUrl)\n }\n }\n\n if (typeof url === 'function') {\n getUrl()\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [displayed._rev])\n\n if (!displayUrl || typeof displayUrl !== 'string') {\n return (\n <ThemeProvider>\n <Flex padding={5} items=\"center\" justify=\"center\">\n <Spinner />\n </Flex>\n </ThemeProvider>\n )\n }\n\n return (\n <ThemeProvider>\n <textarea\n style={{position: `absolute`, pointerEvents: `none`, opacity: 0}}\n ref={input}\n value={displayUrl}\n readOnly\n tabIndex={-1}\n />\n <Flex direction=\"column\" style={{height: `100%`}}>\n <Card padding={2} borderBottom={1}>\n <Flex align=\"center\" gap={2}>\n <Flex align=\"center\" gap={1}>\n <Button\n fontSize={[1]}\n padding={2}\n tone=\"primary\"\n mode={iframeSize === 'mobile' ? 'default' : 'ghost'}\n icon={MobileDeviceIcon}\n onClick={() => setIframeSize(iframeSize === 'mobile' ? 'desktop' : 'mobile')}\n />\n </Flex>\n <Box flex={1}>\n <Text size={0} textOverflow=\"ellipsis\">\n {displayUrl}\n </Text>\n </Box>\n <Flex align=\"center\" gap={1}>\n {reload?.button ? (\n <Button\n fontSize={[1]}\n padding={2}\n icon={UndoIcon}\n title=\"Reload\"\n aria-label=\"Reload\"\n onClick={() => handleReload()}\n />\n ) : null}\n <Button\n fontSize={[1]}\n icon={CopyIcon}\n padding={[2]}\n title=\"Copy\"\n aria-label=\"Copy\"\n onClick={() => handleCopy()}\n />\n <Button\n fontSize={[1]}\n icon={LeaveIcon}\n padding={[2]}\n text=\"Open\"\n tone=\"primary\"\n onClick={() => window.open(displayUrl)}\n />\n </Flex>\n </Flex>\n </Card>\n <Card tone=\"transparent\" padding={iframeSize === 'mobile' ? 2 : 0} style={{height: `100%`}}>\n <Flex align=\"center\" justify=\"center\" style={{height: `100%`}}>\n <iframe\n ref={iframe}\n title=\"preview\"\n style={sizes[iframeSize]}\n frameBorder=\"0\"\n src={displayUrl}\n />\n </Flex>\n </Card>\n </Flex>\n </ThemeProvider>\n )\n}\n\nexport default Iframe\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"Iframe.js","names":["sizes","desktop","backgroundColor","width","height","maxHeight","mobile","Iframe","props","sanityDocument","document","options","url","defaultSize","reload","attributes","useState","displayUrl","setDisplayUrl","iframeSize","setIframeSize","input","useRef","iframe","displayed","useCopyToClipboard","copy","handleCopy","current","value","handleReload","src","useEffect","revision","setTimeout","Number","_rev","getUrl","resolveUrl","position","pointerEvents","opacity","MobileDeviceIcon","button","UndoIcon","CopyIcon","LeaveIcon","window","open"],"sources":["../src/Iframe.tsx"],"sourcesContent":["import React, {useEffect, useState, useRef} from 'react'\nimport {SanityDocumentLike} from 'sanity'\nimport {Box, Flex, Text, Button, ThemeProvider, Card, Spinner} from '@sanity/ui'\nimport {UndoIcon, CopyIcon, LeaveIcon, MobileDeviceIcon} from '@sanity/icons'\n\nimport useCopyToClipboard from './hooks/useCopytoClipboard'\n\nconst sizes = {\n desktop: {backgroundColor: `white`, width: `100%`, height: `100%`, maxHeight: `100%`},\n mobile: {backgroundColor: `white`, width: 414, height: `100%`, maxHeight: 736},\n}\n\nexport type IframeOptions = {\n url: string | ((document: SanityDocumentLike) => unknown)\n defaultSize?: 'desktop' | 'mobile'\n reload: {\n revision: boolean | number\n button: boolean\n }\n attributes?: Partial<{\n allow: string\n referrerPolicy: string\n sandbox: string\n }>\n}\n\nexport type IframeProps = {\n document: {\n displayed: SanityDocumentLike\n }\n options: IframeOptions\n}\n\nfunction Iframe(props: IframeProps) {\n const {document: sanityDocument, options} = props\n const {url, defaultSize = `desktop`, reload, attributes = {}} = options\n const [displayUrl, setDisplayUrl] = useState(typeof url === 'string' ? url : ``)\n const [iframeSize, setIframeSize] = useState(defaultSize)\n const input = useRef()\n const iframe = useRef()\n const {displayed} = sanityDocument\n const [, copy] = useCopyToClipboard()\n\n function handleCopy() {\n if (!input?.current?.value) return\n\n copy(input.current.value)\n }\n\n function handleReload() {\n if (!iframe?.current) {\n return\n }\n\n // Funky way to reload an iframe without CORS issuies\n // eslint-disable-next-line no-self-assign\n iframe.current.src = iframe.current.src\n }\n\n // Reload on new revisions\n useEffect(() => {\n if (reload?.revision || reload?.revision == 0) {\n setTimeout(() => {\n handleReload()\n }, Number(reload?.revision))\n }\n }, [displayed._rev, reload?.revision])\n\n // Set initial URL and refresh on new revisions\n useEffect(() => {\n const getUrl = async () => {\n const resolveUrl = typeof url === 'function' ? await url(displayed) : ``\n\n // Only update state if URL has changed\n if (resolveUrl !== displayUrl) {\n setDisplayUrl(resolveUrl)\n }\n }\n\n if (typeof url === 'function') {\n getUrl()\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [displayed._rev])\n\n if (!displayUrl || typeof displayUrl !== 'string') {\n return (\n <ThemeProvider>\n <Flex padding={5} items=\"center\" justify=\"center\">\n <Spinner />\n </Flex>\n </ThemeProvider>\n )\n }\n\n return (\n <ThemeProvider>\n <textarea\n style={{position: `absolute`, pointerEvents: `none`, opacity: 0}}\n ref={input}\n value={displayUrl}\n readOnly\n tabIndex={-1}\n />\n <Flex direction=\"column\" style={{height: `100%`}}>\n <Card padding={2} borderBottom={1}>\n <Flex align=\"center\" gap={2}>\n <Flex align=\"center\" gap={1}>\n <Button\n fontSize={[1]}\n padding={2}\n tone=\"primary\"\n mode={iframeSize === 'mobile' ? 'default' : 'ghost'}\n icon={MobileDeviceIcon}\n onClick={() => setIframeSize(iframeSize === 'mobile' ? 'desktop' : 'mobile')}\n />\n </Flex>\n <Box flex={1}>\n <Text size={0} textOverflow=\"ellipsis\">\n {displayUrl}\n </Text>\n </Box>\n <Flex align=\"center\" gap={1}>\n {reload?.button ? (\n <Button\n fontSize={[1]}\n padding={2}\n icon={UndoIcon}\n title=\"Reload\"\n aria-label=\"Reload\"\n onClick={() => handleReload()}\n />\n ) : null}\n <Button\n fontSize={[1]}\n icon={CopyIcon}\n padding={[2]}\n title=\"Copy\"\n aria-label=\"Copy\"\n onClick={() => handleCopy()}\n />\n <Button\n fontSize={[1]}\n icon={LeaveIcon}\n padding={[2]}\n text=\"Open\"\n tone=\"primary\"\n onClick={() => window.open(displayUrl)}\n />\n </Flex>\n </Flex>\n </Card>\n <Card tone=\"transparent\" padding={iframeSize === 'mobile' ? 2 : 0} style={{height: `100%`}}>\n <Flex align=\"center\" justify=\"center\" style={{height: `100%`}}>\n <iframe\n ref={iframe}\n title=\"preview\"\n style={sizes[iframeSize]}\n frameBorder=\"0\"\n src={displayUrl}\n {...attributes}\n />\n </Flex>\n </Card>\n </Flex>\n </ThemeProvider>\n )\n}\n\nexport default Iframe\n"],"mappings":"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"}
|
|
@@ -4,42 +4,31 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
var _react = require("react");
|
|
9
|
-
|
|
10
8
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
11
|
-
|
|
12
9
|
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
13
|
-
|
|
14
10
|
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
15
|
-
|
|
16
11
|
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."); }
|
|
17
|
-
|
|
18
12
|
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); }
|
|
19
|
-
|
|
20
13
|
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; }
|
|
21
|
-
|
|
22
14
|
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
23
|
-
|
|
24
15
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
25
|
-
|
|
26
16
|
// Return success
|
|
17
|
+
|
|
27
18
|
function useCopyToClipboard() {
|
|
28
19
|
var _useState = (0, _react.useState)(null),
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
20
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
21
|
+
copiedText = _useState2[0],
|
|
22
|
+
setCopiedText = _useState2[1];
|
|
33
23
|
var copy = /*#__PURE__*/function () {
|
|
34
24
|
var _ref = _asyncToGenerator(function* (text) {
|
|
35
25
|
var _navigator;
|
|
36
|
-
|
|
37
26
|
if (!((_navigator = navigator) !== null && _navigator !== void 0 && _navigator.clipboard)) {
|
|
38
27
|
console.warn('Clipboard not supported');
|
|
39
28
|
return false;
|
|
40
|
-
}
|
|
41
|
-
|
|
29
|
+
}
|
|
42
30
|
|
|
31
|
+
// Try to save to clipboard then save it in the state if worked
|
|
43
32
|
try {
|
|
44
33
|
yield navigator.clipboard.writeText(text);
|
|
45
34
|
setCopiedText(text);
|
|
@@ -50,15 +39,12 @@ function useCopyToClipboard() {
|
|
|
50
39
|
return false;
|
|
51
40
|
}
|
|
52
41
|
});
|
|
53
|
-
|
|
54
42
|
return function copy(_x) {
|
|
55
43
|
return _ref.apply(this, arguments);
|
|
56
44
|
};
|
|
57
45
|
}();
|
|
58
|
-
|
|
59
46
|
return [copiedText, copy];
|
|
60
47
|
}
|
|
61
|
-
|
|
62
48
|
var _default = useCopyToClipboard;
|
|
63
49
|
exports.default = _default;
|
|
64
50
|
//# sourceMappingURL=useCopytoClipboard.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCopytoClipboard.js","names":["useCopyToClipboard","useState","copiedText","setCopiedText","copy","text","navigator","clipboard","console","warn","writeText","error"],"sources":["../../src/hooks/useCopytoClipboard.ts"],"sourcesContent":["import {useState} from 'react'\n\ntype CopiedValue = string | null\ntype CopyFn = (text: string) => Promise<boolean> // Return success\n\nfunction useCopyToClipboard(): [CopiedValue, CopyFn] {\n const [copiedText, setCopiedText] = useState<CopiedValue>(null)\n\n const copy: CopyFn = async (text) => {\n if (!navigator?.clipboard) {\n console.warn('Clipboard not supported')\n return false\n }\n\n // Try to save to clipboard then save it in the state if worked\n try {\n await navigator.clipboard.writeText(text)\n setCopiedText(text)\n return true\n } catch (error) {\n console.warn('Copy failed', error)\n setCopiedText(null)\n return false\n }\n }\n\n return [copiedText, copy]\n}\n\nexport default useCopyToClipboard\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"useCopytoClipboard.js","names":["useCopyToClipboard","useState","copiedText","setCopiedText","copy","text","navigator","clipboard","console","warn","writeText","error"],"sources":["../../src/hooks/useCopytoClipboard.ts"],"sourcesContent":["import {useState} from 'react'\n\ntype CopiedValue = string | null\ntype CopyFn = (text: string) => Promise<boolean> // Return success\n\nfunction useCopyToClipboard(): [CopiedValue, CopyFn] {\n const [copiedText, setCopiedText] = useState<CopiedValue>(null)\n\n const copy: CopyFn = async (text) => {\n if (!navigator?.clipboard) {\n console.warn('Clipboard not supported')\n return false\n }\n\n // Try to save to clipboard then save it in the state if worked\n try {\n await navigator.clipboard.writeText(text)\n setCopiedText(text)\n return true\n } catch (error) {\n console.warn('Copy failed', error)\n setCopiedText(null)\n return false\n }\n }\n\n return [copiedText, copy]\n}\n\nexport default useCopyToClipboard\n"],"mappings":";;;;;;AAAA;AAA8B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGmB;;AAEjD,SAASA,kBAAkB,GAA0B;EACnD,gBAAoC,IAAAC,eAAQ,EAAc,IAAI,CAAC;IAAA;IAAxDC,UAAU;IAAEC,aAAa;EAEhC,IAAMC,IAAY;IAAA,6BAAG,WAAOC,IAAI,EAAK;MAAA;MACnC,IAAI,gBAACC,SAAS,uCAAT,WAAWC,SAAS,GAAE;QACzBC,OAAO,CAACC,IAAI,CAAC,yBAAyB,CAAC;QACvC,OAAO,KAAK;MACd;;MAEA;MACA,IAAI;QACF,MAAMH,SAAS,CAACC,SAAS,CAACG,SAAS,CAACL,IAAI,CAAC;QACzCF,aAAa,CAACE,IAAI,CAAC;QACnB,OAAO,IAAI;MACb,CAAC,CAAC,OAAOM,KAAK,EAAE;QACdH,OAAO,CAACC,IAAI,CAAC,aAAa,EAAEE,KAAK,CAAC;QAClCR,aAAa,CAAC,IAAI,CAAC;QACnB,OAAO,KAAK;MACd;IACF,CAAC;IAAA,gBAhBKC,IAAY;MAAA;IAAA;EAAA,GAgBjB;EAED,OAAO,CAACF,UAAU,EAAEE,IAAI,CAAC;AAC3B;AAAC,eAEcJ,kBAAkB;AAAA"}
|
package/package.json
CHANGED
|
@@ -1,39 +1,42 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sanity-plugin-iframe-pane",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.5",
|
|
4
4
|
"description": "Display any URL in a View Pane, along with helpful buttons to Copy the URL or open in a new tab",
|
|
5
|
-
"main": "lib/Iframe.js",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"build": "sanipack build",
|
|
8
|
-
"watch": "sanipack build --watch",
|
|
9
|
-
"prepublishOnly": "sanipack build && sanipack verify",
|
|
10
|
-
"lint": "eslint .",
|
|
11
|
-
"lint:fix": "eslint . --fix"
|
|
12
|
-
},
|
|
13
|
-
"repository": {
|
|
14
|
-
"type": "git",
|
|
15
|
-
"url": "git+ssh://git@github.com/SimeonGriggs/sanity-plugin-iframe-pane.git"
|
|
16
|
-
},
|
|
17
5
|
"keywords": [
|
|
18
6
|
"sanity",
|
|
19
7
|
"sanity-plugin"
|
|
20
8
|
],
|
|
21
|
-
"
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git@github.com:sanity-io/sanity-plugin-iframe-pane.git"
|
|
12
|
+
},
|
|
22
13
|
"license": "MIT",
|
|
14
|
+
"author": "Simeon Griggs <simeon@sanity.io>",
|
|
15
|
+
"main": "lib/Iframe.js",
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "sanipack build",
|
|
18
|
+
"lint": "eslint .",
|
|
19
|
+
"lint:fix": "eslint . --fix",
|
|
20
|
+
"prepublishOnly": "sanipack build && sanipack verify",
|
|
21
|
+
"watch": "sanipack build --watch"
|
|
22
|
+
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@sanity/icons": "^1.2.1",
|
|
25
25
|
"@sanity/ui": "^0.36.12"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
+
"@commitlint/cli": "^17.2.0",
|
|
29
|
+
"@commitlint/config-conventional": "^17.2.0",
|
|
28
30
|
"@sanity/eslint-config-studio": "^2.0.0",
|
|
31
|
+
"@sanity/semantic-release-preset": "^2.0.2",
|
|
29
32
|
"eslint": "8.19.0",
|
|
30
33
|
"eslint-config-prettier": "^8.5.0",
|
|
31
34
|
"eslint-config-sanity": "6.0.0",
|
|
32
35
|
"eslint-plugin-prettier": "^4.2.1",
|
|
33
36
|
"eslint-plugin-react": "^7.30.1",
|
|
34
37
|
"prettier": "2.4.1",
|
|
35
|
-
"sanity": "^2.29.3",
|
|
36
38
|
"sanipack": "2.0.1",
|
|
39
|
+
"sanity": "^2.29.3",
|
|
37
40
|
"typescript": "^4.7.4"
|
|
38
41
|
},
|
|
39
42
|
"peerDependencies": {
|
package/src/Iframe.tsx
CHANGED
|
@@ -17,6 +17,11 @@ export type IframeOptions = {
|
|
|
17
17
|
revision: boolean | number
|
|
18
18
|
button: boolean
|
|
19
19
|
}
|
|
20
|
+
attributes?: Partial<{
|
|
21
|
+
allow: string
|
|
22
|
+
referrerPolicy: string
|
|
23
|
+
sandbox: string
|
|
24
|
+
}>
|
|
20
25
|
}
|
|
21
26
|
|
|
22
27
|
export type IframeProps = {
|
|
@@ -28,7 +33,7 @@ export type IframeProps = {
|
|
|
28
33
|
|
|
29
34
|
function Iframe(props: IframeProps) {
|
|
30
35
|
const {document: sanityDocument, options} = props
|
|
31
|
-
const {url, defaultSize = `desktop`, reload} = options
|
|
36
|
+
const {url, defaultSize = `desktop`, reload, attributes = {}} = options
|
|
32
37
|
const [displayUrl, setDisplayUrl] = useState(typeof url === 'string' ? url : ``)
|
|
33
38
|
const [iframeSize, setIframeSize] = useState(defaultSize)
|
|
34
39
|
const input = useRef()
|
|
@@ -153,6 +158,7 @@ function Iframe(props: IframeProps) {
|
|
|
153
158
|
style={sizes[iframeSize]}
|
|
154
159
|
frameBorder="0"
|
|
155
160
|
src={displayUrl}
|
|
161
|
+
{...attributes}
|
|
156
162
|
/>
|
|
157
163
|
</Flex>
|
|
158
164
|
</Card>
|