sanity-plugin-iframe-pane 2.0.1 → 2.1.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/README.md CHANGED
@@ -43,8 +43,15 @@ S.view
43
43
  // Optional: Add a reload button, or reload on new document revisions
44
44
  reload: {
45
45
  button: true, // default `undefined`
46
- revision: true, // default `undefined`
46
+ revision: true, // boolean | number. default `undefined`. If a number is provided, add a delay (in ms) before the automatic reload on document revision
47
47
  },
48
+ // Optional: Pass attributes to the underlying `iframe` element:
49
+ // See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe
50
+ attributes: {
51
+ allow: 'fullscreen' // string, optional
52
+ referrerPolicy: 'strict-origin-when-cross-origin' // string, optional
53
+ sandbox: 'allow-same-origin' // string, optional
54
+ }
48
55
  })
49
56
  .title('Preview')
50
57
  ```
@@ -67,4 +74,3 @@ Run ["CI & Release" workflow](https://github.com/sanity-io/sanity-plugin-iframe-
67
74
  Make sure to select the studio-v3 branch and check "Release new version".
68
75
 
69
76
  Semantic release will only release on configured branches, so it is safe to run release on any branch.
70
-
package/lib/index.esm.js CHANGED
@@ -1,2 +1,2 @@
1
- import{jsx as e,jsxs as i}from"react/jsx-runtime";import{useState as n,useRef as t,useEffect as o}from"react";import{ThemeProvider as r,Flex as l,Spinner as a,Card as d,Button as c,Box as s,Text as p}from"@sanity/ui";import{MobileDeviceIcon as u,UndoIcon as f,CopyIcon as h,LeaveIcon as g}from"@sanity/icons";import{useCopyToClipboard as m}from"usehooks-ts";const y={desktop:{width:"100%",height:"100%",maxHeight:"100%"},mobile:{width:414,height:"100%",maxHeight:736}},v="desktop";function b(b){const{document:x,options:k}=b,{url:w,defaultSize:z=v,reload:C}=k,[S,j]=n(w&&"string"==typeof w?w:""),[O,B]=n((null==y?void 0:y[z])?z:v),H=t(null),R=t(null),{displayed:_}=x,[,E]=m();function I(){(null==R?void 0:R.current)&&(R.current.src=R.current.src)}return o((()=>{(null==C?void 0:C.revision)&&I()}),[_._rev,null==C?void 0:C.revision]),o((()=>{"function"==typeof w&&(async()=>{const e="function"==typeof w?await w(_):"";e!==S&&e&&"string"==typeof e&&j(e)})()}),[_._rev]),S&&"string"==typeof S?i(r,{children:[e("textarea",{style:{position:"absolute",pointerEvents:"none",opacity:0},ref:H,value:S,readOnly:!0,tabIndex:-1}),i(l,{direction:"column",style:{height:"100%"},children:[e(d,{padding:2,borderBottom:!0,children:i(l,{align:"center",gap:2,children:[e(l,{align:"center",gap:1,children:e(c,{fontSize:[1],padding:2,tone:"primary",mode:"mobile"===O?"default":"ghost",icon:u,onClick:()=>B("mobile"===O?"desktop":"mobile")})}),e(s,{flex:1,children:e(p,{size:0,textOverflow:"ellipsis",children:S})}),i(l,{align:"center",gap:1,children:[(null==C?void 0:C.button)?e(c,{fontSize:[1],padding:2,icon:f,title:"Reload","aria-label":"Reload",onClick:()=>I()}):null,e(c,{fontSize:[1],icon:h,padding:[2],title:"Copy","aria-label":"Copy",onClick:()=>{var e;(null==(e=null==H?void 0:H.current)?void 0:e.value)&&E(H.current.value)}}),e(c,{fontSize:[1],icon:g,padding:[2],text:"Open",tone:"primary",onClick:()=>window.open(S)})]})]})}),e(d,{tone:"transparent",padding:"mobile"===O?2:0,style:{height:"100%"},children:e(l,{align:"center",justify:"center",style:{height:"100%"},children:e("iframe",{ref:R,title:"preview",style:y[O],frameBorder:"0",src:S})})})]})]}):e(r,{children:e(l,{padding:5,align:"center",justify:"center",children:e(a,{})})})}export{b as default};
1
+ function e(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function t(t){for(var i=1;i<arguments.length;i++){var r=null!=arguments[i]?arguments[i]:{};i%2?e(Object(r),!0).forEach((function(e){n(t,e,r[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(r)):e(Object(r)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(r,e))}))}return t}function n(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}import{jsx as i,jsxs as r}from"react/jsx-runtime";import{useState as o,useRef as l,useEffect as c}from"react";import{ThemeProvider as a,Flex as d,Spinner as u,Card as s,Button as p,Box as f,Text as g}from"@sanity/ui";import{MobileDeviceIcon as y,UndoIcon as h,CopyIcon as m,LeaveIcon as b}from"@sanity/icons";import{useCopyToClipboard as v}from"usehooks-ts";const O={desktop:{width:"100%",height:"100%",maxHeight:"100%"},mobile:{width:414,height:"100%",maxHeight:736}},j="desktop";function w(e){const{document:n,options:w}=e,{url:k,defaultSize:x=j,reload:P,attributes:S={}}=w,[z,C]=o(k&&"string"==typeof k?k:""),[D,E]=o((null==O?void 0:O[x])?x:j),B=l(null),H=l(null),{displayed:R}=n,[,_]=v();function I(){(null==H?void 0:H.current)&&(H.current.src=H.current.src)}return c((()=>{((null==P?void 0:P.revision)||0==(null==P?void 0:P.revision))&&setTimeout((()=>{I()}),Number(null==P?void 0:P.revision))}),[R._rev,null==P?void 0:P.revision]),c((()=>{"function"==typeof k&&(async()=>{const e="function"==typeof k?await k(R):"";e!==z&&e&&"string"==typeof e&&C(e)})()}),[R._rev]),z&&"string"==typeof z?r(a,{children:[i("textarea",{style:{position:"absolute",pointerEvents:"none",opacity:0},ref:B,value:z,readOnly:!0,tabIndex:-1}),r(d,{direction:"column",style:{height:"100%"},children:[i(s,{padding:2,borderBottom:!0,children:r(d,{align:"center",gap:2,children:[i(d,{align:"center",gap:1,children:i(p,{fontSize:[1],padding:2,tone:"primary",mode:"mobile"===D?"default":"ghost",icon:y,onClick:()=>E("mobile"===D?"desktop":"mobile")})}),i(f,{flex:1,children:i(g,{size:0,textOverflow:"ellipsis",children:z})}),r(d,{align:"center",gap:1,children:[(null==P?void 0:P.button)?i(p,{fontSize:[1],padding:2,icon:h,title:"Reload","aria-label":"Reload",onClick:()=>I()}):null,i(p,{fontSize:[1],icon:m,padding:[2],title:"Copy","aria-label":"Copy",onClick:()=>{var e;(null==(e=null==B?void 0:B.current)?void 0:e.value)&&_(B.current.value)}}),i(p,{fontSize:[1],icon:b,padding:[2],text:"Open",tone:"primary",onClick:()=>window.open(z)})]})]})}),i(s,{tone:"transparent",padding:"mobile"===D?2:0,style:{height:"100%"},children:i(d,{align:"center",justify:"center",style:{height:"100%"},children:i("iframe",t({ref:H,title:"preview",style:O[D],frameBorder:"0",src:z},S))})})]})]}):i(a,{children:i(d,{padding:5,align:"center",justify:"center",children:i(u,{})})})}export{w as default};
2
2
  //# sourceMappingURL=index.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/Iframe.tsx"],"sourcesContent":["import React, { useEffect, useState, useRef } from \"react\";\nimport { SanityDocumentLike } from \"sanity\";\nimport {\n Box,\n Flex,\n Text,\n Button,\n ThemeProvider,\n Card,\n Spinner,\n} from \"@sanity/ui\";\nimport { UndoIcon, CopyIcon, LeaveIcon, MobileDeviceIcon } from \"@sanity/icons\";\n\nimport { useCopyToClipboard } from \"usehooks-ts\";\n\ntype Size = \"desktop\" | \"mobile\";\n\ntype SizeProps = {\n [key in Size]: {\n width: string | number;\n height: string | number;\n maxHeight: string | number;\n };\n};\n\nconst sizes: SizeProps = {\n desktop: {\n width: `100%`,\n height: `100%`,\n maxHeight: `100%`,\n },\n mobile: {\n width: 414,\n height: `100%`,\n maxHeight: 736,\n },\n};\n\nexport type IframeOptions = {\n url: string | ((document: SanityDocumentLike) => unknown);\n defaultSize?: Size;\n reload?: {\n revision?: boolean;\n button?: boolean;\n };\n};\n\nexport type IframeProps = {\n document: {\n displayed: SanityDocumentLike;\n };\n options: IframeOptions;\n};\n\nconst DEFAULT_SIZE = `desktop`;\n\nfunction Iframe(props: IframeProps) {\n const { document: sanityDocument, options } = props;\n const { url, defaultSize = DEFAULT_SIZE, reload } = options;\n const [displayUrl, setDisplayUrl] = useState(\n url && typeof url === \"string\" ? url : ``\n );\n const [iframeSize, setIframeSize] = useState(\n sizes?.[defaultSize] ? defaultSize : DEFAULT_SIZE\n );\n const input = useRef<HTMLTextAreaElement>(null);\n const iframe = useRef<HTMLIFrameElement>(null);\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) {\n handleReload();\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 (\n resolveUrl !== displayUrl &&\n resolveUrl &&\n typeof resolveUrl === \"string\"\n ) {\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} align=\"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>\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={() =>\n setIframeSize(iframeSize === \"mobile\" ? \"desktop\" : \"mobile\")\n }\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\n tone=\"transparent\"\n padding={iframeSize === \"mobile\" ? 2 : 0}\n style={{ height: `100%` }}\n >\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"],"names":["sizes","desktop","width","height","maxHeight","mobile","DEFAULT_SIZE","Iframe","props","document","sanityDocument","options","url","defaultSize","reload","displayUrl","setDisplayUrl","useState","iframeSize","setIframeSize","input","useRef","iframe","displayed","copy","useCopyToClipboard","handleReload","current","src","useEffect","revision","_rev","async","resolveUrl","getUrl","jsxs","ThemeProvider","children","jsx","style","position","pointerEvents","opacity","ref","value","readOnly","tabIndex","Flex","direction","Card","padding","borderBottom","align","gap","Button","fontSize","tone","mode","icon","MobileDeviceIcon","onClick","Box","flex","Text","size","textOverflow","button","UndoIcon","title","CopyIcon","_a","LeaveIcon","text","window","open","justify","frameBorder","Spinner"],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","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'\nimport {HTMLAttributeReferrerPolicy} from 'react'\n\nimport {useCopyToClipboard} from 'usehooks-ts'\n\ntype Size = 'desktop' | 'mobile'\n\ntype SizeProps = {\n // eslint-disable-next-line no-unused-vars\n [key in Size]: {\n width: string | number\n height: string | number\n maxHeight: string | number\n }\n}\n\nconst sizes: SizeProps = {\n desktop: {\n width: `100%`,\n height: `100%`,\n maxHeight: `100%`,\n },\n mobile: {\n width: 414,\n height: `100%`,\n maxHeight: 736,\n },\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: HTMLAttributeReferrerPolicy | undefined\n sandbox: string\n }>\n}\n\nexport type IframeProps = {\n document: {\n displayed: SanityDocumentLike\n }\n options: IframeOptions\n}\n\nconst DEFAULT_SIZE = `desktop`\n\nfunction Iframe(props: IframeProps) {\n const {document: sanityDocument, options} = props\n const {url, defaultSize = DEFAULT_SIZE, reload, attributes = {}} = options\n const [displayUrl, setDisplayUrl] = useState(url && typeof url === 'string' ? url : ``)\n const [iframeSize, setIframeSize] = useState(sizes?.[defaultSize] ? defaultSize : DEFAULT_SIZE)\n const input = useRef<HTMLTextAreaElement>(null)\n const iframe = useRef<HTMLIFrameElement>(null)\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 && resolveUrl && typeof resolveUrl === 'string') {\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} align=\"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>\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"],"names":["sizes","desktop","width","height","maxHeight","mobile","DEFAULT_SIZE","Iframe","props","document","sanityDocument","options","url","defaultSize","reload","attributes","displayUrl","setDisplayUrl","useState","iframeSize","setIframeSize","input","useRef","iframe","displayed","copy","useCopyToClipboard","handleReload","current","src","useEffect","revision","setTimeout","Number","_rev","async","resolveUrl","getUrl","jsxs","ThemeProvider","children","jsx","style","position","pointerEvents","opacity","ref","value","readOnly","tabIndex","Flex","direction","Card","padding","borderBottom","align","gap","Button","fontSize","tone","mode","icon","MobileDeviceIcon","onClick","Box","flex","Text","size","textOverflow","button","UndoIcon","title","CopyIcon","_a","LeaveIcon","text","window","open","justify","_objectSpread","frameBorder","Spinner"],"mappings":"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"}
package/lib/index.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var e=require("react/jsx-runtime"),n=require("react"),i=require("@sanity/ui"),t=require("@sanity/icons"),o=require("usehooks-ts");const r={desktop:{width:"100%",height:"100%",maxHeight:"100%"},mobile:{width:414,height:"100%",maxHeight:736}},l="desktop";module.exports=function(s){const{document:d,options:a}=s,{url:c,defaultSize:u=l,reload:p}=a,[x,h]=n.useState(c&&"string"==typeof c?c:""),[f,g]=n.useState((null==r?void 0:r[u])?u:l),y=n.useRef(null),v=n.useRef(null),{displayed:j}=d,[,m]=o.useCopyToClipboard();function b(){(null==v?void 0:v.current)&&(v.current.src=v.current.src)}return n.useEffect((()=>{(null==p?void 0:p.revision)&&b()}),[j._rev,null==p?void 0:p.revision]),n.useEffect((()=>{"function"==typeof c&&(async()=>{const e="function"==typeof c?await c(j):"";e!==x&&e&&"string"==typeof e&&h(e)})()}),[j._rev]),x&&"string"==typeof x?e.jsxs(i.ThemeProvider,{children:[e.jsx("textarea",{style:{position:"absolute",pointerEvents:"none",opacity:0},ref:y,value:x,readOnly:!0,tabIndex:-1}),e.jsxs(i.Flex,{direction:"column",style:{height:"100%"},children:[e.jsx(i.Card,{padding:2,borderBottom:!0,children:e.jsxs(i.Flex,{align:"center",gap:2,children:[e.jsx(i.Flex,{align:"center",gap:1,children:e.jsx(i.Button,{fontSize:[1],padding:2,tone:"primary",mode:"mobile"===f?"default":"ghost",icon:t.MobileDeviceIcon,onClick:()=>g("mobile"===f?"desktop":"mobile")})}),e.jsx(i.Box,{flex:1,children:e.jsx(i.Text,{size:0,textOverflow:"ellipsis",children:x})}),e.jsxs(i.Flex,{align:"center",gap:1,children:[(null==p?void 0:p.button)?e.jsx(i.Button,{fontSize:[1],padding:2,icon:t.UndoIcon,title:"Reload","aria-label":"Reload",onClick:()=>b()}):null,e.jsx(i.Button,{fontSize:[1],icon:t.CopyIcon,padding:[2],title:"Copy","aria-label":"Copy",onClick:()=>{var e;(null==(e=null==y?void 0:y.current)?void 0:e.value)&&m(y.current.value)}}),e.jsx(i.Button,{fontSize:[1],icon:t.LeaveIcon,padding:[2],text:"Open",tone:"primary",onClick:()=>window.open(x)})]})]})}),e.jsx(i.Card,{tone:"transparent",padding:"mobile"===f?2:0,style:{height:"100%"},children:e.jsx(i.Flex,{align:"center",justify:"center",style:{height:"100%"},children:e.jsx("iframe",{ref:v,title:"preview",style:r[f],frameBorder:"0",src:x})})})]})]}):e.jsx(i.ThemeProvider,{children:e.jsx(i.Flex,{padding:5,align:"center",justify:"center",children:e.jsx(i.Spinner,{})})})};
1
+ "use strict";function e(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function t(t){for(var r=1;r<arguments.length;r++){var i=null!=arguments[r]?arguments[r]:{};r%2?e(Object(i),!0).forEach((function(e){n(t,e,i[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(i)):e(Object(i)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(i,e))}))}return t}function n(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var r=require("react/jsx-runtime"),i=require("react"),o=require("@sanity/ui"),l=require("@sanity/icons"),s=require("usehooks-ts");const c={desktop:{width:"100%",height:"100%",maxHeight:"100%"},mobile:{width:414,height:"100%",maxHeight:736}},u="desktop";module.exports=function(e){const{document:n,options:a}=e,{url:d,defaultSize:p=u,reload:f,attributes:x={}}=a,[y,g]=i.useState(d&&"string"==typeof d?d:""),[h,j]=i.useState((null==c?void 0:c[p])?p:u),b=i.useRef(null),v=i.useRef(null),{displayed:m}=n,[,O]=s.useCopyToClipboard();function w(){(null==v?void 0:v.current)&&(v.current.src=v.current.src)}return i.useEffect((()=>{((null==f?void 0:f.revision)||0==(null==f?void 0:f.revision))&&setTimeout((()=>{w()}),Number(null==f?void 0:f.revision))}),[m._rev,null==f?void 0:f.revision]),i.useEffect((()=>{"function"==typeof d&&(async()=>{const e="function"==typeof d?await d(m):"";e!==y&&e&&"string"==typeof e&&g(e)})()}),[m._rev]),y&&"string"==typeof y?r.jsxs(o.ThemeProvider,{children:[r.jsx("textarea",{style:{position:"absolute",pointerEvents:"none",opacity:0},ref:b,value:y,readOnly:!0,tabIndex:-1}),r.jsxs(o.Flex,{direction:"column",style:{height:"100%"},children:[r.jsx(o.Card,{padding:2,borderBottom:!0,children:r.jsxs(o.Flex,{align:"center",gap:2,children:[r.jsx(o.Flex,{align:"center",gap:1,children:r.jsx(o.Button,{fontSize:[1],padding:2,tone:"primary",mode:"mobile"===h?"default":"ghost",icon:l.MobileDeviceIcon,onClick:()=>j("mobile"===h?"desktop":"mobile")})}),r.jsx(o.Box,{flex:1,children:r.jsx(o.Text,{size:0,textOverflow:"ellipsis",children:y})}),r.jsxs(o.Flex,{align:"center",gap:1,children:[(null==f?void 0:f.button)?r.jsx(o.Button,{fontSize:[1],padding:2,icon:l.UndoIcon,title:"Reload","aria-label":"Reload",onClick:()=>w()}):null,r.jsx(o.Button,{fontSize:[1],icon:l.CopyIcon,padding:[2],title:"Copy","aria-label":"Copy",onClick:()=>{var e;(null==(e=null==b?void 0:b.current)?void 0:e.value)&&O(b.current.value)}}),r.jsx(o.Button,{fontSize:[1],icon:l.LeaveIcon,padding:[2],text:"Open",tone:"primary",onClick:()=>window.open(y)})]})]})}),r.jsx(o.Card,{tone:"transparent",padding:"mobile"===h?2:0,style:{height:"100%"},children:r.jsx(o.Flex,{align:"center",justify:"center",style:{height:"100%"},children:r.jsx("iframe",t({ref:v,title:"preview",style:c[h],frameBorder:"0",src:y},x))})})]})]}):r.jsx(o.ThemeProvider,{children:r.jsx(o.Flex,{padding:5,align:"center",justify:"center",children:r.jsx(o.Spinner,{})})})};
2
2
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/Iframe.tsx"],"sourcesContent":["import React, { useEffect, useState, useRef } from \"react\";\nimport { SanityDocumentLike } from \"sanity\";\nimport {\n Box,\n Flex,\n Text,\n Button,\n ThemeProvider,\n Card,\n Spinner,\n} from \"@sanity/ui\";\nimport { UndoIcon, CopyIcon, LeaveIcon, MobileDeviceIcon } from \"@sanity/icons\";\n\nimport { useCopyToClipboard } from \"usehooks-ts\";\n\ntype Size = \"desktop\" | \"mobile\";\n\ntype SizeProps = {\n [key in Size]: {\n width: string | number;\n height: string | number;\n maxHeight: string | number;\n };\n};\n\nconst sizes: SizeProps = {\n desktop: {\n width: `100%`,\n height: `100%`,\n maxHeight: `100%`,\n },\n mobile: {\n width: 414,\n height: `100%`,\n maxHeight: 736,\n },\n};\n\nexport type IframeOptions = {\n url: string | ((document: SanityDocumentLike) => unknown);\n defaultSize?: Size;\n reload?: {\n revision?: boolean;\n button?: boolean;\n };\n};\n\nexport type IframeProps = {\n document: {\n displayed: SanityDocumentLike;\n };\n options: IframeOptions;\n};\n\nconst DEFAULT_SIZE = `desktop`;\n\nfunction Iframe(props: IframeProps) {\n const { document: sanityDocument, options } = props;\n const { url, defaultSize = DEFAULT_SIZE, reload } = options;\n const [displayUrl, setDisplayUrl] = useState(\n url && typeof url === \"string\" ? url : ``\n );\n const [iframeSize, setIframeSize] = useState(\n sizes?.[defaultSize] ? defaultSize : DEFAULT_SIZE\n );\n const input = useRef<HTMLTextAreaElement>(null);\n const iframe = useRef<HTMLIFrameElement>(null);\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) {\n handleReload();\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 (\n resolveUrl !== displayUrl &&\n resolveUrl &&\n typeof resolveUrl === \"string\"\n ) {\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} align=\"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>\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={() =>\n setIframeSize(iframeSize === \"mobile\" ? \"desktop\" : \"mobile\")\n }\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\n tone=\"transparent\"\n padding={iframeSize === \"mobile\" ? 2 : 0}\n style={{ height: `100%` }}\n >\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"],"names":["sizes","desktop","width","height","maxHeight","mobile","DEFAULT_SIZE","props","document","sanityDocument","options","url","defaultSize","reload","displayUrl","setDisplayUrl","useState","iframeSize","setIframeSize","input","useRef","iframe","displayed","copy","useCopyToClipboard","handleReload","current","src","useEffect","revision","_rev","async","resolveUrl","getUrl","jsxs","ThemeProvider","children","jsx","style","position","pointerEvents","opacity","ref","value","readOnly","tabIndex","Flex","direction","Card","padding","borderBottom","align","gap","Button","fontSize","tone","mode","icon","MobileDeviceIcon","onClick","Box","flex","Text","size","textOverflow","button","UndoIcon","title","CopyIcon","_a","LeaveIcon","text","window","open","justify","frameBorder","Spinner"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","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'\nimport {HTMLAttributeReferrerPolicy} from 'react'\n\nimport {useCopyToClipboard} from 'usehooks-ts'\n\ntype Size = 'desktop' | 'mobile'\n\ntype SizeProps = {\n // eslint-disable-next-line no-unused-vars\n [key in Size]: {\n width: string | number\n height: string | number\n maxHeight: string | number\n }\n}\n\nconst sizes: SizeProps = {\n desktop: {\n width: `100%`,\n height: `100%`,\n maxHeight: `100%`,\n },\n mobile: {\n width: 414,\n height: `100%`,\n maxHeight: 736,\n },\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: HTMLAttributeReferrerPolicy | undefined\n sandbox: string\n }>\n}\n\nexport type IframeProps = {\n document: {\n displayed: SanityDocumentLike\n }\n options: IframeOptions\n}\n\nconst DEFAULT_SIZE = `desktop`\n\nfunction Iframe(props: IframeProps) {\n const {document: sanityDocument, options} = props\n const {url, defaultSize = DEFAULT_SIZE, reload, attributes = {}} = options\n const [displayUrl, setDisplayUrl] = useState(url && typeof url === 'string' ? url : ``)\n const [iframeSize, setIframeSize] = useState(sizes?.[defaultSize] ? defaultSize : DEFAULT_SIZE)\n const input = useRef<HTMLTextAreaElement>(null)\n const iframe = useRef<HTMLIFrameElement>(null)\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 && resolveUrl && typeof resolveUrl === 'string') {\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} align=\"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>\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"],"names":["sizes","desktop","width","height","maxHeight","mobile","DEFAULT_SIZE","props","document","sanityDocument","options","url","defaultSize","reload","attributes","displayUrl","setDisplayUrl","useState","iframeSize","setIframeSize","input","useRef","iframe","displayed","copy","useCopyToClipboard","handleReload","current","src","useEffect","revision","setTimeout","Number","_rev","async","resolveUrl","getUrl","jsxs","ThemeProvider","children","jsx","style","position","pointerEvents","opacity","ref","value","readOnly","tabIndex","Flex","direction","Card","padding","borderBottom","align","gap","Button","fontSize","tone","mode","icon","MobileDeviceIcon","onClick","Box","flex","Text","size","textOverflow","button","UndoIcon","title","CopyIcon","_a","LeaveIcon","text","window","open","justify","_objectSpread","frameBorder","Spinner"],"mappings":"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"}
@@ -1,5 +1,4 @@
1
- /// <reference types="react" />
2
-
1
+ import {HTMLAttributeReferrerPolicy} from 'react'
3
2
  import {SanityDocumentLike} from 'sanity'
4
3
 
5
4
  declare function Iframe(props: IframeProps): JSX.Element
@@ -9,11 +8,16 @@ export declare type IframeOptions = IframeOptions_2
9
8
 
10
9
  declare type IframeOptions_2 = {
11
10
  url: string | ((document: SanityDocumentLike) => unknown)
12
- defaultSize?: Size
13
- reload?: {
14
- revision?: boolean
15
- button?: boolean
11
+ defaultSize?: 'desktop' | 'mobile'
12
+ reload: {
13
+ revision: boolean | number
14
+ button: boolean
16
15
  }
16
+ attributes?: Partial<{
17
+ allow: string
18
+ referrerPolicy: HTMLAttributeReferrerPolicy | undefined
19
+ sandbox: string
20
+ }>
17
21
  }
18
22
 
19
23
  declare type IframeProps = {
@@ -23,6 +27,4 @@ declare type IframeProps = {
23
27
  options: IframeOptions_2
24
28
  }
25
29
 
26
- declare type Size = 'desktop' | 'mobile'
27
-
28
30
  export {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sanity-plugin-iframe-pane",
3
- "version": "2.0.1",
3
+ "version": "2.1.1",
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
  "homepage": "https://github.com/sanity-io/sanity-plugin-iframe-pane#readme",
6
6
  "bugs": {
@@ -43,9 +43,9 @@
43
43
  "watch": "pkg-utils watch"
44
44
  },
45
45
  "dependencies": {
46
- "@sanity/icons": "^1.3.1",
46
+ "@sanity/icons": "^2.0.0",
47
47
  "@sanity/incompatible-plugin": "^1.0.4",
48
- "@sanity/ui": "1.0.0-beta.32",
48
+ "@sanity/ui": "^1.0.0",
49
49
  "usehooks-ts": "^2.6.0"
50
50
  },
51
51
  "devDependencies": {
@@ -68,12 +68,12 @@
68
68
  "prettier-plugin-packagejson": "^2.3.0",
69
69
  "react": "^18",
70
70
  "rimraf": "^3.0.2",
71
- "sanity": "3.0.0-rc.2",
71
+ "sanity": "^3.0.0",
72
72
  "typescript": "^4.8.4"
73
73
  },
74
74
  "peerDependencies": {
75
75
  "react": "^18",
76
- "sanity": "dev-preview || 3.0.0-rc.2"
76
+ "sanity": "^3.0.0"
77
77
  },
78
78
  "engines": {
79
79
  "node": ">=14"
package/src/Iframe.tsx CHANGED
@@ -1,27 +1,21 @@
1
- import React, { useEffect, useState, useRef } from "react";
2
- import { SanityDocumentLike } from "sanity";
3
- import {
4
- Box,
5
- Flex,
6
- Text,
7
- Button,
8
- ThemeProvider,
9
- Card,
10
- Spinner,
11
- } from "@sanity/ui";
12
- import { UndoIcon, CopyIcon, LeaveIcon, MobileDeviceIcon } from "@sanity/icons";
13
-
14
- import { useCopyToClipboard } from "usehooks-ts";
15
-
16
- type Size = "desktop" | "mobile";
1
+ import React, {useEffect, useState, useRef} from 'react'
2
+ import {SanityDocumentLike} from 'sanity'
3
+ import {Box, Flex, Text, Button, ThemeProvider, Card, Spinner} from '@sanity/ui'
4
+ import {UndoIcon, CopyIcon, LeaveIcon, MobileDeviceIcon} from '@sanity/icons'
5
+ import {HTMLAttributeReferrerPolicy} from 'react'
6
+
7
+ import {useCopyToClipboard} from 'usehooks-ts'
8
+
9
+ type Size = 'desktop' | 'mobile'
17
10
 
18
11
  type SizeProps = {
12
+ // eslint-disable-next-line no-unused-vars
19
13
  [key in Size]: {
20
- width: string | number;
21
- height: string | number;
22
- maxHeight: string | number;
23
- };
24
- };
14
+ width: string | number
15
+ height: string | number
16
+ maxHeight: string | number
17
+ }
18
+ }
25
19
 
26
20
  const sizes: SizeProps = {
27
21
  desktop: {
@@ -34,104 +28,103 @@ const sizes: SizeProps = {
34
28
  height: `100%`,
35
29
  maxHeight: 736,
36
30
  },
37
- };
31
+ }
38
32
 
39
33
  export type IframeOptions = {
40
- url: string | ((document: SanityDocumentLike) => unknown);
41
- defaultSize?: Size;
42
- reload?: {
43
- revision?: boolean;
44
- button?: boolean;
45
- };
46
- };
34
+ url: string | ((document: SanityDocumentLike) => unknown)
35
+ defaultSize?: 'desktop' | 'mobile'
36
+ reload: {
37
+ revision: boolean | number
38
+ button: boolean
39
+ }
40
+ attributes?: Partial<{
41
+ allow: string
42
+ referrerPolicy: HTMLAttributeReferrerPolicy | undefined
43
+ sandbox: string
44
+ }>
45
+ }
47
46
 
48
47
  export type IframeProps = {
49
48
  document: {
50
- displayed: SanityDocumentLike;
51
- };
52
- options: IframeOptions;
53
- };
49
+ displayed: SanityDocumentLike
50
+ }
51
+ options: IframeOptions
52
+ }
54
53
 
55
- const DEFAULT_SIZE = `desktop`;
54
+ const DEFAULT_SIZE = `desktop`
56
55
 
57
56
  function Iframe(props: IframeProps) {
58
- const { document: sanityDocument, options } = props;
59
- const { url, defaultSize = DEFAULT_SIZE, reload } = options;
60
- const [displayUrl, setDisplayUrl] = useState(
61
- url && typeof url === "string" ? url : ``
62
- );
63
- const [iframeSize, setIframeSize] = useState(
64
- sizes?.[defaultSize] ? defaultSize : DEFAULT_SIZE
65
- );
66
- const input = useRef<HTMLTextAreaElement>(null);
67
- const iframe = useRef<HTMLIFrameElement>(null);
68
- const { displayed } = sanityDocument;
69
- const [, copy] = useCopyToClipboard();
57
+ const {document: sanityDocument, options} = props
58
+ const {url, defaultSize = DEFAULT_SIZE, reload, attributes = {}} = options
59
+ const [displayUrl, setDisplayUrl] = useState(url && typeof url === 'string' ? url : ``)
60
+ const [iframeSize, setIframeSize] = useState(sizes?.[defaultSize] ? defaultSize : DEFAULT_SIZE)
61
+ const input = useRef<HTMLTextAreaElement>(null)
62
+ const iframe = useRef<HTMLIFrameElement>(null)
63
+ const {displayed} = sanityDocument
64
+ const [, copy] = useCopyToClipboard()
70
65
 
71
66
  function handleCopy() {
72
- if (!input?.current?.value) return;
67
+ if (!input?.current?.value) return
73
68
 
74
- copy(input.current.value);
69
+ copy(input.current.value)
75
70
  }
76
71
 
77
72
  function handleReload() {
78
73
  if (!iframe?.current) {
79
- return;
74
+ return
80
75
  }
81
76
 
82
77
  // Funky way to reload an iframe without CORS issuies
83
78
  // eslint-disable-next-line no-self-assign
84
- iframe.current.src = iframe.current.src;
79
+ iframe.current.src = iframe.current.src
85
80
  }
86
81
 
87
82
  // Reload on new revisions
88
83
  useEffect(() => {
89
- if (reload?.revision) {
90
- handleReload();
84
+ if (reload?.revision || reload?.revision == 0) {
85
+ setTimeout(() => {
86
+ handleReload()
87
+ }, Number(reload?.revision))
91
88
  }
92
- }, [displayed._rev, reload?.revision]);
89
+ }, [displayed._rev, reload?.revision])
93
90
 
94
91
  // Set initial URL and refresh on new revisions
95
92
  useEffect(() => {
96
93
  const getUrl = async () => {
97
- const resolveUrl = typeof url === "function" ? await url(displayed) : ``;
94
+ const resolveUrl = typeof url === 'function' ? await url(displayed) : ``
98
95
 
99
96
  // Only update state if URL has changed
100
- if (
101
- resolveUrl !== displayUrl &&
102
- resolveUrl &&
103
- typeof resolveUrl === "string"
104
- ) {
105
- setDisplayUrl(resolveUrl);
97
+ if (resolveUrl !== displayUrl && resolveUrl && typeof resolveUrl === 'string') {
98
+ setDisplayUrl(resolveUrl)
106
99
  }
107
- };
100
+ }
108
101
 
109
- if (typeof url === "function") {
110
- getUrl();
102
+ if (typeof url === 'function') {
103
+ getUrl()
111
104
  }
112
105
  // eslint-disable-next-line react-hooks/exhaustive-deps
113
- }, [displayed._rev]);
106
+ }, [displayed._rev])
114
107
 
115
- if (!displayUrl || typeof displayUrl !== "string") {
108
+ if (!displayUrl || typeof displayUrl !== 'string') {
116
109
  return (
117
110
  <ThemeProvider>
118
111
  <Flex padding={5} align="center" justify="center">
119
112
  <Spinner />
120
113
  </Flex>
121
114
  </ThemeProvider>
122
- );
115
+ )
123
116
  }
124
117
 
125
118
  return (
126
119
  <ThemeProvider>
127
120
  <textarea
128
- style={{ position: `absolute`, pointerEvents: `none`, opacity: 0 }}
121
+ style={{position: `absolute`, pointerEvents: `none`, opacity: 0}}
129
122
  ref={input}
130
123
  value={displayUrl}
131
124
  readOnly
132
125
  tabIndex={-1}
133
126
  />
134
- <Flex direction="column" style={{ height: `100%` }}>
127
+ <Flex direction="column" style={{height: `100%`}}>
135
128
  <Card padding={2} borderBottom>
136
129
  <Flex align="center" gap={2}>
137
130
  <Flex align="center" gap={1}>
@@ -139,11 +132,9 @@ function Iframe(props: IframeProps) {
139
132
  fontSize={[1]}
140
133
  padding={2}
141
134
  tone="primary"
142
- mode={iframeSize === "mobile" ? "default" : "ghost"}
135
+ mode={iframeSize === 'mobile' ? 'default' : 'ghost'}
143
136
  icon={MobileDeviceIcon}
144
- onClick={() =>
145
- setIframeSize(iframeSize === "mobile" ? "desktop" : "mobile")
146
- }
137
+ onClick={() => setIframeSize(iframeSize === 'mobile' ? 'desktop' : 'mobile')}
147
138
  />
148
139
  </Flex>
149
140
  <Box flex={1}>
@@ -181,24 +172,21 @@ function Iframe(props: IframeProps) {
181
172
  </Flex>
182
173
  </Flex>
183
174
  </Card>
184
- <Card
185
- tone="transparent"
186
- padding={iframeSize === "mobile" ? 2 : 0}
187
- style={{ height: `100%` }}
188
- >
189
- <Flex align="center" justify="center" style={{ height: `100%` }}>
175
+ <Card tone="transparent" padding={iframeSize === 'mobile' ? 2 : 0} style={{height: `100%`}}>
176
+ <Flex align="center" justify="center" style={{height: `100%`}}>
190
177
  <iframe
191
178
  ref={iframe}
192
179
  title="preview"
193
180
  style={sizes[iframeSize]}
194
181
  frameBorder="0"
195
182
  src={displayUrl}
183
+ {...attributes}
196
184
  />
197
185
  </Flex>
198
186
  </Card>
199
187
  </Flex>
200
188
  </ThemeProvider>
201
- );
189
+ )
202
190
  }
203
191
 
204
- export default Iframe;
192
+ export default Iframe