sanity-plugin-iframe-pane 1.1.3 → 1.1.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/README.md CHANGED
@@ -38,6 +38,13 @@ S.view
38
38
  button: true, // default `undefined`
39
39
  revision: true, // boolean | number. default `undefined`. If a number is provided, add a delay (in ms) before the automatic reload on document revision
40
40
  },
41
+ // Optional: Pass attributes to the underlying `iframe` element:
42
+ // See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe
43
+ attributes: {
44
+ allow: 'fullscreen' // string, optional
45
+ referrerPolicy: 'strict-origin-when-cross-origin' // string, optional
46
+ sandbox: 'allow-same-origin' // string, optional
47
+ }
41
48
  })
42
49
  .title("Preview");
43
50
  ```
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
- options = props.options;
39
+ options = props.options;
56
40
  var url = options.url,
57
- _options$defaultSize = options.defaultSize,
58
- defaultSize = _options$defaultSize === void 0 ? "desktop" : _options$defaultSize,
59
- reload = options.reload;
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
- _useState2 = _slicedToArray(_useState, 2),
63
- displayUrl = _useState2[0],
64
- setDisplayUrl = _useState2[1];
65
-
47
+ _useState2 = _slicedToArray(_useState, 2),
48
+ displayUrl = _useState2[0],
49
+ setDisplayUrl = _useState2[1];
66
50
  var _useState3 = (0, _react.useState)(defaultSize),
67
- _useState4 = _slicedToArray(_useState3, 2),
68
- iframeSize = _useState4[0],
69
- setIframeSize = _useState4[1];
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
- _useCopyToClipboard2 = _slicedToArray(_useCopyToClipboard, 2),
77
- copy = _useCopyToClipboard2[1];
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
- } // Funky way to reload an iframe without CORS issuies
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
- } // Reload on new revisions
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]); // Set initial URL and refresh on new revisions
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) : ""; // Only update state if URL has changed
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
- } // eslint-disable-next-line react-hooks/exhaustive-deps
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":"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"}
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
- _useState2 = _slicedToArray(_useState, 2),
30
- copiedText = _useState2[0],
31
- setCopiedText = _useState2[1];
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
- } // Try to save to clipboard then save it in the state if worked
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":";;;;;;;AAAA;;;;;;;;;;;;;;;;;;AAGiD;AAEjD,SAASA,kBAAT,GAAqD;EACnD,gBAAoC,IAAAC,eAAA,EAAsB,IAAtB,CAApC;EAAA;EAAA,IAAOC,UAAP;EAAA,IAAmBC,aAAnB;;EAEA,IAAMC,IAAY;IAAA,6BAAG,WAAOC,IAAP,EAAgB;MAAA;;MACnC,IAAI,gBAACC,SAAD,uCAAC,WAAWC,SAAZ,CAAJ,EAA2B;QACzBC,OAAO,CAACC,IAAR,CAAa,yBAAb;QACA,OAAO,KAAP;MACD,CAJkC,CAMnC;;;MACA,IAAI;QACF,MAAMH,SAAS,CAACC,SAAV,CAAoBG,SAApB,CAA8BL,IAA9B,CAAN;QACAF,aAAa,CAACE,IAAD,CAAb;QACA,OAAO,IAAP;MACD,CAJD,CAIE,OAAOM,KAAP,EAAc;QACdH,OAAO,CAACC,IAAR,CAAa,aAAb,EAA4BE,KAA5B;QACAR,aAAa,CAAC,IAAD,CAAb;QACA,OAAO,KAAP;MACD;IACF,CAhBiB;;IAAA,gBAAZC,IAAY;MAAA;IAAA;EAAA,GAAlB;;EAkBA,OAAO,CAACF,UAAD,EAAaE,IAAb,CAAP;AACD;;eAEcJ,kB"}
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,6 +1,6 @@
1
1
  {
2
2
  "name": "sanity-plugin-iframe-pane",
3
- "version": "1.1.3",
3
+ "version": "1.1.4",
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
5
  "main": "lib/Iframe.js",
6
6
  "scripts": {
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>