sanity-plugin-iframe-pane 1.1.4 → 2.0.1-v3-studio.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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2021 Simeon Griggs
3
+ Copyright (c) 2022 Simeon Griggs
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,8 +1,10 @@
1
1
  # sanity-plugin-iframe-pane
2
2
 
3
- > NOTE This is for the Studio v2 version of the plugin
3
+ > **NOTE**
4
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)
5
+ > This is the **Sanity Studio v3 version** of sanity-plugin-iframe-pane.
6
+ >
7
+ > For the v2 version, please refer to the [v2-branch](https://github.com/sanity-io/sanity-plugin-iframe-pane).
6
8
 
7
9
  Display any URL in a View Pane, along with helpful buttons to Copy the URL or open in a new tab.
8
10
 
@@ -13,14 +15,22 @@ Accepts either a string or an async function to resolve a URL based on the curre
13
15
  ## Installation
14
16
 
15
17
  ```
16
- sanity install iframe-pane
18
+ npm install --save sanity-plugin-iframe-pane@studio-v3
19
+ ```
20
+
21
+ or
22
+
23
+ ```
24
+ yarn add sanity-plugin-iframe-pane@studio-v3
17
25
  ```
18
26
 
27
+ ## Usage
28
+
19
29
  This is designed to be used as a [Component inside of a View](https://www.sanity.io/docs/structure-builder-reference#c0c8284844b7).
20
30
 
21
31
  ```js
22
32
  // ./src/deskStructure.js
23
- import Iframe from "sanity-plugin-iframe-pane";
33
+ import Iframe from 'sanity-plugin-iframe-pane'
24
34
 
25
35
  // ...all other list items
26
36
 
@@ -36,20 +46,27 @@ S.view
36
46
  // Optional: Add a reload button, or reload on new document revisions
37
47
  reload: {
38
48
  button: true, // default `undefined`
39
- revision: true, // boolean | number. default `undefined`. If a number is provided, add a delay (in ms) before the automatic reload on document revision
49
+ revision: true, // default `undefined`
40
50
  },
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
- }
48
51
  })
49
- .title("Preview");
52
+ .title('Preview')
50
53
  ```
51
54
 
52
55
  ## License
53
56
 
54
- MIT © Simeon Griggs
55
- See LICENSE
57
+ MIT-licensed. See LICENSE.
58
+
59
+ ## Develop & test
60
+
61
+ This plugin uses [@sanity/plugin-kit](https://github.com/sanity-io/plugin-kit)
62
+ with default configuration for build & watch scripts.
63
+
64
+ See [Testing a plugin in Sanity Studio](https://github.com/sanity-io/plugin-kit#testing-a-plugin-in-sanity-studio)
65
+ on how to run this plugin with hotreload in the studio.
66
+
67
+ ### Release new version
68
+
69
+ Run ["CI & Release" workflow](https://github.com/sanity-io/sanity-plugin-iframe-pane/actions/workflows/main.yml).
70
+ Make sure to select the studio-v3 branch and check "Release new version".
71
+
72
+ Semantic release will only release on configured branches, so it is safe to run release on any branch.
@@ -0,0 +1,204 @@
1
+ var $k7rGe$reactjsxruntime = require("react/jsx-runtime");
2
+ var $k7rGe$react = require("react");
3
+ var $k7rGe$sanityui = require("@sanity/ui");
4
+ var $k7rGe$sanityicons = require("@sanity/icons");
5
+ var $k7rGe$usehooksts = require("usehooks-ts");
6
+
7
+ function $parcel$defineInteropFlag(a) {
8
+ Object.defineProperty(a, '__esModule', {value: true, configurable: true});
9
+ }
10
+ function $parcel$export(e, n, v, s) {
11
+ Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
12
+ }
13
+
14
+ $parcel$defineInteropFlag(module.exports);
15
+
16
+ $parcel$export(module.exports, "default", () => $244e63ca53592e4d$export$2e2bcd8739ae039);
17
+
18
+
19
+
20
+
21
+
22
+ const $f4b318483f84cb22$var$sizes = {
23
+ desktop: {
24
+ width: `100%`,
25
+ height: `100%`,
26
+ maxHeight: `100%`
27
+ },
28
+ mobile: {
29
+ width: 414,
30
+ height: `100%`,
31
+ maxHeight: 736
32
+ }
33
+ };
34
+ const $f4b318483f84cb22$var$DEFAULT_SIZE = `desktop`;
35
+ function $f4b318483f84cb22$var$Iframe(props) {
36
+ const { document: sanityDocument , options: options } = props;
37
+ const { url: url , defaultSize: defaultSize = $f4b318483f84cb22$var$DEFAULT_SIZE , reload: reload } = options;
38
+ const [displayUrl, setDisplayUrl] = (0, $k7rGe$react.useState)(url && typeof url === "string" ? url : ``);
39
+ const [iframeSize, setIframeSize] = (0, $k7rGe$react.useState)($f4b318483f84cb22$var$sizes?.[defaultSize] ? defaultSize : $f4b318483f84cb22$var$DEFAULT_SIZE);
40
+ const input = (0, $k7rGe$react.useRef)(null);
41
+ const iframe = (0, $k7rGe$react.useRef)(null);
42
+ const { displayed: displayed } = sanityDocument;
43
+ const [, copy] = (0, $k7rGe$usehooksts.useCopyToClipboard)();
44
+ function handleCopy() {
45
+ if (!input?.current?.value) return;
46
+ copy(input.current.value);
47
+ }
48
+ function handleReload() {
49
+ if (!iframe?.current) return;
50
+ // Funky way to reload an iframe without CORS issuies
51
+ // eslint-disable-next-line no-self-assign
52
+ iframe.current.src = iframe.current.src;
53
+ }
54
+ // Reload on new revisions
55
+ (0, $k7rGe$react.useEffect)(()=>{
56
+ if (reload?.revision) handleReload();
57
+ }, [
58
+ displayed._rev,
59
+ reload?.revision
60
+ ]);
61
+ // Set initial URL and refresh on new revisions
62
+ (0, $k7rGe$react.useEffect)(()=>{
63
+ const getUrl = async ()=>{
64
+ const resolveUrl = typeof url === "function" ? await url(displayed) : ``;
65
+ // Only update state if URL has changed
66
+ if (resolveUrl !== displayUrl && resolveUrl && typeof resolveUrl === "string") setDisplayUrl(resolveUrl);
67
+ };
68
+ if (typeof url === "function") getUrl();
69
+ // eslint-disable-next-line react-hooks/exhaustive-deps
70
+ }, [
71
+ displayed._rev
72
+ ]);
73
+ if (!displayUrl || typeof displayUrl !== "string") return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.ThemeProvider), {
74
+ children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Flex), {
75
+ padding: 5,
76
+ align: "center",
77
+ justify: "center",
78
+ children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Spinner), {})
79
+ })
80
+ });
81
+ return /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsxs)((0, $k7rGe$sanityui.ThemeProvider), {
82
+ children: [
83
+ /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)("textarea", {
84
+ style: {
85
+ position: `absolute`,
86
+ pointerEvents: `none`,
87
+ opacity: 0
88
+ },
89
+ ref: input,
90
+ value: displayUrl,
91
+ readOnly: true,
92
+ tabIndex: -1
93
+ }),
94
+ /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsxs)((0, $k7rGe$sanityui.Flex), {
95
+ direction: "column",
96
+ style: {
97
+ height: `100%`
98
+ },
99
+ children: [
100
+ /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Card), {
101
+ padding: 2,
102
+ borderBottom: true,
103
+ children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsxs)((0, $k7rGe$sanityui.Flex), {
104
+ align: "center",
105
+ gap: 2,
106
+ children: [
107
+ /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Flex), {
108
+ align: "center",
109
+ gap: 1,
110
+ children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Button), {
111
+ fontSize: [
112
+ 1
113
+ ],
114
+ padding: 2,
115
+ tone: "primary",
116
+ mode: iframeSize === "mobile" ? "default" : "ghost",
117
+ icon: (0, $k7rGe$sanityicons.MobileDeviceIcon),
118
+ onClick: ()=>setIframeSize(iframeSize === "mobile" ? "desktop" : "mobile")
119
+ })
120
+ }),
121
+ /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Box), {
122
+ flex: 1,
123
+ children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Text), {
124
+ size: 0,
125
+ textOverflow: "ellipsis",
126
+ children: displayUrl
127
+ })
128
+ }),
129
+ /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsxs)((0, $k7rGe$sanityui.Flex), {
130
+ align: "center",
131
+ gap: 1,
132
+ children: [
133
+ reload?.button ? /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Button), {
134
+ fontSize: [
135
+ 1
136
+ ],
137
+ padding: 2,
138
+ icon: (0, $k7rGe$sanityicons.UndoIcon),
139
+ title: "Reload",
140
+ "aria-label": "Reload",
141
+ onClick: ()=>handleReload()
142
+ }) : null,
143
+ /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Button), {
144
+ fontSize: [
145
+ 1
146
+ ],
147
+ icon: (0, $k7rGe$sanityicons.CopyIcon),
148
+ padding: [
149
+ 2
150
+ ],
151
+ title: "Copy",
152
+ "aria-label": "Copy",
153
+ onClick: ()=>handleCopy()
154
+ }),
155
+ /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Button), {
156
+ fontSize: [
157
+ 1
158
+ ],
159
+ icon: (0, $k7rGe$sanityicons.LeaveIcon),
160
+ padding: [
161
+ 2
162
+ ],
163
+ text: "Open",
164
+ tone: "primary",
165
+ onClick: ()=>window.open(displayUrl)
166
+ })
167
+ ]
168
+ })
169
+ ]
170
+ })
171
+ }),
172
+ /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Card), {
173
+ tone: "transparent",
174
+ padding: iframeSize === "mobile" ? 2 : 0,
175
+ style: {
176
+ height: `100%`
177
+ },
178
+ children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)((0, $k7rGe$sanityui.Flex), {
179
+ align: "center",
180
+ justify: "center",
181
+ style: {
182
+ height: `100%`
183
+ },
184
+ children: /*#__PURE__*/ (0, $k7rGe$reactjsxruntime.jsx)("iframe", {
185
+ ref: iframe,
186
+ title: "preview",
187
+ style: $f4b318483f84cb22$var$sizes[iframeSize],
188
+ frameBorder: "0",
189
+ src: displayUrl
190
+ })
191
+ })
192
+ })
193
+ ]
194
+ })
195
+ ]
196
+ });
197
+ }
198
+ var $f4b318483f84cb22$export$2e2bcd8739ae039 = $f4b318483f84cb22$var$Iframe;
199
+
200
+
201
+ var $244e63ca53592e4d$export$2e2bcd8739ae039 = (0, $f4b318483f84cb22$export$2e2bcd8739ae039);
202
+
203
+
204
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"mappings":"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","sources":["src/index.ts","src/Iframe.tsx"],"sourcesContent":["import IframeComponent, {IframeOptions as IframeOptionsType} from './Iframe'\n\nexport default IframeComponent\n\nexport type IframeOptions = IframeOptionsType\n","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":[],"version":3,"file":"index.js.map","sourceRoot":"../../"}
@@ -0,0 +1,195 @@
1
+ import {jsx as $gGrEF$jsx, jsxs as $gGrEF$jsxs} from "react/jsx-runtime";
2
+ import {useState as $gGrEF$useState, useRef as $gGrEF$useRef, useEffect as $gGrEF$useEffect} from "react";
3
+ import {ThemeProvider as $gGrEF$ThemeProvider, Flex as $gGrEF$Flex, Spinner as $gGrEF$Spinner, Card as $gGrEF$Card, Button as $gGrEF$Button, Box as $gGrEF$Box, Text as $gGrEF$Text} from "@sanity/ui";
4
+ import {MobileDeviceIcon as $gGrEF$MobileDeviceIcon, UndoIcon as $gGrEF$UndoIcon, CopyIcon as $gGrEF$CopyIcon, LeaveIcon as $gGrEF$LeaveIcon} from "@sanity/icons";
5
+ import {useCopyToClipboard as $gGrEF$useCopyToClipboard} from "usehooks-ts";
6
+
7
+
8
+
9
+
10
+
11
+
12
+ const $b1fbe8f05b2a0ffa$var$sizes = {
13
+ desktop: {
14
+ width: `100%`,
15
+ height: `100%`,
16
+ maxHeight: `100%`
17
+ },
18
+ mobile: {
19
+ width: 414,
20
+ height: `100%`,
21
+ maxHeight: 736
22
+ }
23
+ };
24
+ const $b1fbe8f05b2a0ffa$var$DEFAULT_SIZE = `desktop`;
25
+ function $b1fbe8f05b2a0ffa$var$Iframe(props) {
26
+ const { document: sanityDocument , options: options } = props;
27
+ const { url: url , defaultSize: defaultSize = $b1fbe8f05b2a0ffa$var$DEFAULT_SIZE , reload: reload } = options;
28
+ const [displayUrl, setDisplayUrl] = (0, $gGrEF$useState)(url && typeof url === "string" ? url : ``);
29
+ const [iframeSize, setIframeSize] = (0, $gGrEF$useState)($b1fbe8f05b2a0ffa$var$sizes?.[defaultSize] ? defaultSize : $b1fbe8f05b2a0ffa$var$DEFAULT_SIZE);
30
+ const input = (0, $gGrEF$useRef)(null);
31
+ const iframe = (0, $gGrEF$useRef)(null);
32
+ const { displayed: displayed } = sanityDocument;
33
+ const [, copy] = (0, $gGrEF$useCopyToClipboard)();
34
+ function handleCopy() {
35
+ if (!input?.current?.value) return;
36
+ copy(input.current.value);
37
+ }
38
+ function handleReload() {
39
+ if (!iframe?.current) return;
40
+ // Funky way to reload an iframe without CORS issuies
41
+ // eslint-disable-next-line no-self-assign
42
+ iframe.current.src = iframe.current.src;
43
+ }
44
+ // Reload on new revisions
45
+ (0, $gGrEF$useEffect)(()=>{
46
+ if (reload?.revision) handleReload();
47
+ }, [
48
+ displayed._rev,
49
+ reload?.revision
50
+ ]);
51
+ // Set initial URL and refresh on new revisions
52
+ (0, $gGrEF$useEffect)(()=>{
53
+ const getUrl = async ()=>{
54
+ const resolveUrl = typeof url === "function" ? await url(displayed) : ``;
55
+ // Only update state if URL has changed
56
+ if (resolveUrl !== displayUrl && resolveUrl && typeof resolveUrl === "string") setDisplayUrl(resolveUrl);
57
+ };
58
+ if (typeof url === "function") getUrl();
59
+ // eslint-disable-next-line react-hooks/exhaustive-deps
60
+ }, [
61
+ displayed._rev
62
+ ]);
63
+ if (!displayUrl || typeof displayUrl !== "string") return /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$ThemeProvider), {
64
+ children: /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$Flex), {
65
+ padding: 5,
66
+ align: "center",
67
+ justify: "center",
68
+ children: /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$Spinner), {})
69
+ })
70
+ });
71
+ return /*#__PURE__*/ (0, $gGrEF$jsxs)((0, $gGrEF$ThemeProvider), {
72
+ children: [
73
+ /*#__PURE__*/ (0, $gGrEF$jsx)("textarea", {
74
+ style: {
75
+ position: `absolute`,
76
+ pointerEvents: `none`,
77
+ opacity: 0
78
+ },
79
+ ref: input,
80
+ value: displayUrl,
81
+ readOnly: true,
82
+ tabIndex: -1
83
+ }),
84
+ /*#__PURE__*/ (0, $gGrEF$jsxs)((0, $gGrEF$Flex), {
85
+ direction: "column",
86
+ style: {
87
+ height: `100%`
88
+ },
89
+ children: [
90
+ /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$Card), {
91
+ padding: 2,
92
+ borderBottom: true,
93
+ children: /*#__PURE__*/ (0, $gGrEF$jsxs)((0, $gGrEF$Flex), {
94
+ align: "center",
95
+ gap: 2,
96
+ children: [
97
+ /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$Flex), {
98
+ align: "center",
99
+ gap: 1,
100
+ children: /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$Button), {
101
+ fontSize: [
102
+ 1
103
+ ],
104
+ padding: 2,
105
+ tone: "primary",
106
+ mode: iframeSize === "mobile" ? "default" : "ghost",
107
+ icon: (0, $gGrEF$MobileDeviceIcon),
108
+ onClick: ()=>setIframeSize(iframeSize === "mobile" ? "desktop" : "mobile")
109
+ })
110
+ }),
111
+ /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$Box), {
112
+ flex: 1,
113
+ children: /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$Text), {
114
+ size: 0,
115
+ textOverflow: "ellipsis",
116
+ children: displayUrl
117
+ })
118
+ }),
119
+ /*#__PURE__*/ (0, $gGrEF$jsxs)((0, $gGrEF$Flex), {
120
+ align: "center",
121
+ gap: 1,
122
+ children: [
123
+ reload?.button ? /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$Button), {
124
+ fontSize: [
125
+ 1
126
+ ],
127
+ padding: 2,
128
+ icon: (0, $gGrEF$UndoIcon),
129
+ title: "Reload",
130
+ "aria-label": "Reload",
131
+ onClick: ()=>handleReload()
132
+ }) : null,
133
+ /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$Button), {
134
+ fontSize: [
135
+ 1
136
+ ],
137
+ icon: (0, $gGrEF$CopyIcon),
138
+ padding: [
139
+ 2
140
+ ],
141
+ title: "Copy",
142
+ "aria-label": "Copy",
143
+ onClick: ()=>handleCopy()
144
+ }),
145
+ /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$Button), {
146
+ fontSize: [
147
+ 1
148
+ ],
149
+ icon: (0, $gGrEF$LeaveIcon),
150
+ padding: [
151
+ 2
152
+ ],
153
+ text: "Open",
154
+ tone: "primary",
155
+ onClick: ()=>window.open(displayUrl)
156
+ })
157
+ ]
158
+ })
159
+ ]
160
+ })
161
+ }),
162
+ /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$Card), {
163
+ tone: "transparent",
164
+ padding: iframeSize === "mobile" ? 2 : 0,
165
+ style: {
166
+ height: `100%`
167
+ },
168
+ children: /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$Flex), {
169
+ align: "center",
170
+ justify: "center",
171
+ style: {
172
+ height: `100%`
173
+ },
174
+ children: /*#__PURE__*/ (0, $gGrEF$jsx)("iframe", {
175
+ ref: iframe,
176
+ title: "preview",
177
+ style: $b1fbe8f05b2a0ffa$var$sizes[iframeSize],
178
+ frameBorder: "0",
179
+ src: displayUrl
180
+ })
181
+ })
182
+ })
183
+ ]
184
+ })
185
+ ]
186
+ });
187
+ }
188
+ var $b1fbe8f05b2a0ffa$export$2e2bcd8739ae039 = $b1fbe8f05b2a0ffa$var$Iframe;
189
+
190
+
191
+ var $df9eabe9bda49ea8$export$2e2bcd8739ae039 = (0, $b1fbe8f05b2a0ffa$export$2e2bcd8739ae039);
192
+
193
+
194
+ export {$df9eabe9bda49ea8$export$2e2bcd8739ae039 as default};
195
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"mappings":"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","sources":["src/index.ts","src/Iframe.tsx"],"sourcesContent":["import IframeComponent, {IframeOptions as IframeOptionsType} from './Iframe'\n\nexport default IframeComponent\n\nexport type IframeOptions = IframeOptionsType\n","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":[],"version":3,"file":"index.js.map","sourceRoot":"../../"}
@@ -0,0 +1,21 @@
1
+ import { SanityDocumentLike } from "sanity";
2
+ type Size = "desktop" | "mobile";
3
+ type _IframeOptions1 = {
4
+ url: string | ((document: SanityDocumentLike) => unknown);
5
+ defaultSize?: Size;
6
+ reload?: {
7
+ revision?: boolean;
8
+ button?: boolean;
9
+ };
10
+ };
11
+ type IframeProps = {
12
+ document: {
13
+ displayed: SanityDocumentLike;
14
+ };
15
+ options: _IframeOptions1;
16
+ };
17
+ declare function Iframe(props: IframeProps): JSX.Element;
18
+ export default IframeComponent;
19
+ export type IframeOptions = _IframeOptions1;
20
+
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"mappings":";AAeA,YAAY,SAAS,GAAG,QAAQ,CAAC;AAuBjC,uBAA4B;IAC1B,GAAG,EAAE,MAAM,GAAG,CAAC,CAAC,QAAQ,EAAE,kBAAkB,KAAK,OAAO,CAAC,CAAC;IAC1D,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,MAAM,CAAC,EAAE;QACP,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;CACH,CAAC;AAEF,mBAA0B;IACxB,QAAQ,EAAE;QACR,SAAS,EAAE,kBAAkB,CAAC;KAC/B,CAAC;IACF,OAAO,EAAE,eAAa,CAAC;CACxB,CAAC;AAIF,wBAAgB,KAAK,EAAE,WAAW,eAiJjC;ACvMD,eAAe,eAAe,CAAA;AAE9B,4BAA4B,eAAiB,CAAA","sources":["src/src/Iframe.tsx","src/src/index.ts","src/index.ts"],"sourcesContent":[null,null,"import IframeComponent, {IframeOptions as IframeOptionsType} from './Iframe'\n\nexport default IframeComponent\n\nexport type IframeOptions = IframeOptionsType\n"],"names":[],"version":3,"file":"index.d.ts.map","sourceRoot":"../../"}
package/package.json CHANGED
@@ -1,42 +1,78 @@
1
1
  {
2
2
  "name": "sanity-plugin-iframe-pane",
3
- "version": "1.1.4",
3
+ "version": "2.0.1-v3-studio.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
- "main": "lib/Iframe.js",
5
+ "author": "Simeon Griggs <simeon@sanity.io>",
6
+ "license": "MIT",
7
+ "source": "./src/index.ts",
8
+ "main": "./lib/cjs/index.js",
9
+ "module": "./lib/esm/index.js",
10
+ "types": "./lib/types/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "require": "./lib/cjs/index.js",
14
+ "default": "./lib/esm/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "src",
19
+ "lib",
20
+ "v2-incompatible.js",
21
+ "sanity.json"
22
+ ],
6
23
  "scripts": {
7
- "build": "sanipack build",
8
- "watch": "sanipack build --watch",
9
- "prepublishOnly": "sanipack build && sanipack verify",
24
+ "clean": "rimraf lib",
10
25
  "lint": "eslint .",
11
- "lint:fix": "eslint . --fix"
26
+ "prebuild": "npm run clean && plugin-kit verify-package --silent",
27
+ "build": "parcel build --no-cache",
28
+ "watch": "parcel watch",
29
+ "link-watch": "plugin-kit link-watch",
30
+ "prepublishOnly": "npm run build",
31
+ "prepare": "husky install"
12
32
  },
13
33
  "repository": {
14
34
  "type": "git",
15
- "url": "git+ssh://git@github.com/SimeonGriggs/sanity-plugin-iframe-pane.git"
35
+ "url": "git@github.com:sanity-io/sanity-plugin-iframe-pane.git"
36
+ },
37
+ "engines": {
38
+ "node": ">=14.0.0"
16
39
  },
17
- "keywords": [
18
- "sanity",
19
- "sanity-plugin"
20
- ],
21
- "author": "Simeon Griggs <simeon@sanity.io>",
22
- "license": "MIT",
23
40
  "dependencies": {
24
- "@sanity/icons": "^1.2.1",
25
- "@sanity/ui": "^0.36.12"
41
+ "@sanity/icons": "^1.3.1",
42
+ "@sanity/incompatible-plugin": "^1.0.4",
43
+ "@sanity/ui": "^1.0.0-beta.31",
44
+ "usehooks-ts": "^2.6.0"
26
45
  },
27
46
  "devDependencies": {
28
- "@sanity/eslint-config-studio": "^2.0.0",
29
- "eslint": "8.19.0",
47
+ "@commitlint/cli": "^17.1.2",
48
+ "@commitlint/config-conventional": "^17.1.0",
49
+ "@parcel/packager-ts": "^2.6.2",
50
+ "@parcel/transformer-typescript-types": "^2.6.2",
51
+ "@sanity/plugin-kit": "^1.1.0-ecosystem-preset.9",
52
+ "@sanity/semantic-release-preset": "^2.0.2",
53
+ "@typescript-eslint/eslint-plugin": "^5.41.0",
54
+ "@typescript-eslint/parser": "^5.41.0",
55
+ "eslint": "^8.26.0",
30
56
  "eslint-config-prettier": "^8.5.0",
31
- "eslint-config-sanity": "6.0.0",
57
+ "eslint-config-sanity": "^6.0.0",
32
58
  "eslint-plugin-prettier": "^4.2.1",
33
- "eslint-plugin-react": "^7.30.1",
34
- "prettier": "2.4.1",
35
- "sanity": "^2.29.3",
36
- "sanipack": "2.0.1",
37
- "typescript": "^4.7.4"
59
+ "eslint-plugin-react": "^7.31.10",
60
+ "eslint-plugin-react-hooks": "^4.6.0",
61
+ "husky": "^8.0.1",
62
+ "lint-staged": "^13.0.3",
63
+ "parcel": "~2.6.0",
64
+ "prettier": "^2.7.1",
65
+ "react": "^18.0.0",
66
+ "rimraf": "^3.0.2",
67
+ "sanity": "dev-preview || 3.0.0-dev-preview.22",
68
+ "typescript": "~4.7.0"
38
69
  },
39
70
  "peerDependencies": {
40
- "react": "^17.0.2"
41
- }
71
+ "react": "^18.0.0",
72
+ "sanity": "dev-preview || 3.0.0-dev-preview.22"
73
+ },
74
+ "bugs": {
75
+ "url": "https://github.com/sanity-io/sanity-plugin-iframe-pane/issues"
76
+ },
77
+ "homepage": "https://github.com/sanity-io/sanity-plugin-iframe-pane#readme"
42
78
  }
package/sanity.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
- "paths": {
3
- "source": "./src",
4
- "compiled": "./lib"
5
- },
6
- "parts": []
7
- }
2
+ "parts": [
3
+ {
4
+ "implements": "part:@sanity/base/sanity-root",
5
+ "path": "./v2-incompatible.js"
6
+ }
7
+ ]
8
+ }
package/src/Iframe.tsx CHANGED
@@ -1,118 +1,149 @@
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
-
6
- import useCopyToClipboard from './hooks/useCopytoClipboard'
7
-
8
- const sizes = {
9
- desktop: {backgroundColor: `white`, width: `100%`, height: `100%`, maxHeight: `100%`},
10
- mobile: {backgroundColor: `white`, width: 414, height: `100%`, maxHeight: 736},
11
- }
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";
17
+
18
+ type SizeProps = {
19
+ [key in Size]: {
20
+ width: string | number;
21
+ height: string | number;
22
+ maxHeight: string | number;
23
+ };
24
+ };
25
+
26
+ const sizes: SizeProps = {
27
+ desktop: {
28
+ width: `100%`,
29
+ height: `100%`,
30
+ maxHeight: `100%`,
31
+ },
32
+ mobile: {
33
+ width: 414,
34
+ height: `100%`,
35
+ maxHeight: 736,
36
+ },
37
+ };
12
38
 
13
39
  export type IframeOptions = {
14
- url: string | ((document: SanityDocumentLike) => unknown)
15
- defaultSize?: 'desktop' | 'mobile'
16
- reload: {
17
- revision: boolean | number
18
- button: boolean
19
- }
20
- attributes?: Partial<{
21
- allow: string
22
- referrerPolicy: string
23
- sandbox: string
24
- }>
25
- }
40
+ url: string | ((document: SanityDocumentLike) => unknown);
41
+ defaultSize?: Size;
42
+ reload?: {
43
+ revision?: boolean;
44
+ button?: boolean;
45
+ };
46
+ };
26
47
 
27
48
  export type IframeProps = {
28
49
  document: {
29
- displayed: SanityDocumentLike
30
- }
31
- options: IframeOptions
32
- }
50
+ displayed: SanityDocumentLike;
51
+ };
52
+ options: IframeOptions;
53
+ };
54
+
55
+ const DEFAULT_SIZE = `desktop`;
33
56
 
34
57
  function Iframe(props: IframeProps) {
35
- const {document: sanityDocument, options} = props
36
- const {url, defaultSize = `desktop`, reload, attributes = {}} = options
37
- const [displayUrl, setDisplayUrl] = useState(typeof url === 'string' ? url : ``)
38
- const [iframeSize, setIframeSize] = useState(defaultSize)
39
- const input = useRef()
40
- const iframe = useRef()
41
- const {displayed} = sanityDocument
42
- const [, copy] = useCopyToClipboard()
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();
43
70
 
44
71
  function handleCopy() {
45
- if (!input?.current?.value) return
72
+ if (!input?.current?.value) return;
46
73
 
47
- copy(input.current.value)
74
+ copy(input.current.value);
48
75
  }
49
76
 
50
77
  function handleReload() {
51
78
  if (!iframe?.current) {
52
- return
79
+ return;
53
80
  }
54
81
 
55
82
  // Funky way to reload an iframe without CORS issuies
56
83
  // eslint-disable-next-line no-self-assign
57
- iframe.current.src = iframe.current.src
84
+ iframe.current.src = iframe.current.src;
58
85
  }
59
86
 
60
87
  // Reload on new revisions
61
88
  useEffect(() => {
62
- if (reload?.revision || reload?.revision == 0) {
63
- setTimeout(() => {
64
- handleReload()
65
- }, Number(reload?.revision))
89
+ if (reload?.revision) {
90
+ handleReload();
66
91
  }
67
- }, [displayed._rev, reload?.revision])
92
+ }, [displayed._rev, reload?.revision]);
68
93
 
69
94
  // Set initial URL and refresh on new revisions
70
95
  useEffect(() => {
71
96
  const getUrl = async () => {
72
- const resolveUrl = typeof url === 'function' ? await url(displayed) : ``
97
+ const resolveUrl = typeof url === "function" ? await url(displayed) : ``;
73
98
 
74
99
  // Only update state if URL has changed
75
- if (resolveUrl !== displayUrl) {
76
- setDisplayUrl(resolveUrl)
100
+ if (
101
+ resolveUrl !== displayUrl &&
102
+ resolveUrl &&
103
+ typeof resolveUrl === "string"
104
+ ) {
105
+ setDisplayUrl(resolveUrl);
77
106
  }
78
- }
107
+ };
79
108
 
80
- if (typeof url === 'function') {
81
- getUrl()
109
+ if (typeof url === "function") {
110
+ getUrl();
82
111
  }
83
112
  // eslint-disable-next-line react-hooks/exhaustive-deps
84
- }, [displayed._rev])
113
+ }, [displayed._rev]);
85
114
 
86
- if (!displayUrl || typeof displayUrl !== 'string') {
115
+ if (!displayUrl || typeof displayUrl !== "string") {
87
116
  return (
88
117
  <ThemeProvider>
89
- <Flex padding={5} items="center" justify="center">
118
+ <Flex padding={5} align="center" justify="center">
90
119
  <Spinner />
91
120
  </Flex>
92
121
  </ThemeProvider>
93
- )
122
+ );
94
123
  }
95
124
 
96
125
  return (
97
126
  <ThemeProvider>
98
127
  <textarea
99
- style={{position: `absolute`, pointerEvents: `none`, opacity: 0}}
128
+ style={{ position: `absolute`, pointerEvents: `none`, opacity: 0 }}
100
129
  ref={input}
101
130
  value={displayUrl}
102
131
  readOnly
103
132
  tabIndex={-1}
104
133
  />
105
- <Flex direction="column" style={{height: `100%`}}>
106
- <Card padding={2} borderBottom={1}>
134
+ <Flex direction="column" style={{ height: `100%` }}>
135
+ <Card padding={2} borderBottom>
107
136
  <Flex align="center" gap={2}>
108
137
  <Flex align="center" gap={1}>
109
138
  <Button
110
139
  fontSize={[1]}
111
140
  padding={2}
112
141
  tone="primary"
113
- mode={iframeSize === 'mobile' ? 'default' : 'ghost'}
142
+ mode={iframeSize === "mobile" ? "default" : "ghost"}
114
143
  icon={MobileDeviceIcon}
115
- onClick={() => setIframeSize(iframeSize === 'mobile' ? 'desktop' : 'mobile')}
144
+ onClick={() =>
145
+ setIframeSize(iframeSize === "mobile" ? "desktop" : "mobile")
146
+ }
116
147
  />
117
148
  </Flex>
118
149
  <Box flex={1}>
@@ -150,21 +181,24 @@ function Iframe(props: IframeProps) {
150
181
  </Flex>
151
182
  </Flex>
152
183
  </Card>
153
- <Card tone="transparent" padding={iframeSize === 'mobile' ? 2 : 0} style={{height: `100%`}}>
154
- <Flex align="center" justify="center" style={{height: `100%`}}>
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%` }}>
155
190
  <iframe
156
191
  ref={iframe}
157
192
  title="preview"
158
193
  style={sizes[iframeSize]}
159
194
  frameBorder="0"
160
195
  src={displayUrl}
161
- {...attributes}
162
196
  />
163
197
  </Flex>
164
198
  </Card>
165
199
  </Flex>
166
200
  </ThemeProvider>
167
- )
201
+ );
168
202
  }
169
203
 
170
- export default Iframe
204
+ export default Iframe;
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ import IframeComponent, {IframeOptions as IframeOptionsType} from './Iframe'
2
+
3
+ export default IframeComponent
4
+
5
+ export type IframeOptions = IframeOptionsType
@@ -0,0 +1,11 @@
1
+ const {showIncompatiblePluginDialog} = require('@sanity/incompatible-plugin')
2
+ const {name, version, sanityExchangeUrl} = require('./package.json')
3
+
4
+ export default showIncompatiblePluginDialog({
5
+ name: name,
6
+ versions: {
7
+ v3: version,
8
+ v2: undefined,
9
+ },
10
+ sanityExchangeUrl,
11
+ })
package/.babelrc DELETED
@@ -1,3 +0,0 @@
1
- {
2
- "extends": "sanipack/babel"
3
- }
package/lib/Iframe.js DELETED
@@ -1,193 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
- var _react = _interopRequireWildcard(require("react"));
8
- var _ui = require("@sanity/ui");
9
- var _icons = require("@sanity/icons");
10
- var _useCopytoClipboard = _interopRequireDefault(require("./hooks/useCopytoClipboard"));
11
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
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); }
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; }
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); }
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); } }
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); }); }; }
17
- function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
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."); }
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); }
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; }
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; }
22
- function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
23
- var sizes = {
24
- desktop: {
25
- backgroundColor: "white",
26
- width: "100%",
27
- height: "100%",
28
- maxHeight: "100%"
29
- },
30
- mobile: {
31
- backgroundColor: "white",
32
- width: 414,
33
- height: "100%",
34
- maxHeight: 736
35
- }
36
- };
37
- function Iframe(props) {
38
- var sanityDocument = props.document,
39
- options = props.options;
40
- var url = options.url,
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;
46
- var _useState = (0, _react.useState)(typeof url === 'string' ? url : ""),
47
- _useState2 = _slicedToArray(_useState, 2),
48
- displayUrl = _useState2[0],
49
- setDisplayUrl = _useState2[1];
50
- var _useState3 = (0, _react.useState)(defaultSize),
51
- _useState4 = _slicedToArray(_useState3, 2),
52
- iframeSize = _useState4[0],
53
- setIframeSize = _useState4[1];
54
- var input = (0, _react.useRef)();
55
- var iframe = (0, _react.useRef)();
56
- var displayed = sanityDocument.displayed;
57
- var _useCopyToClipboard = (0, _useCopytoClipboard.default)(),
58
- _useCopyToClipboard2 = _slicedToArray(_useCopyToClipboard, 2),
59
- copy = _useCopyToClipboard2[1];
60
- function handleCopy() {
61
- var _input$current;
62
- if (!(input !== null && input !== void 0 && (_input$current = input.current) !== null && _input$current !== void 0 && _input$current.value)) return;
63
- copy(input.current.value);
64
- }
65
- function handleReload() {
66
- if (!(iframe !== null && iframe !== void 0 && iframe.current)) {
67
- return;
68
- }
69
-
70
- // Funky way to reload an iframe without CORS issuies
71
- // eslint-disable-next-line no-self-assign
72
- iframe.current.src = iframe.current.src;
73
- }
74
-
75
- // Reload on new revisions
76
- (0, _react.useEffect)(() => {
77
- if (reload !== null && reload !== void 0 && reload.revision || (reload === null || reload === void 0 ? void 0 : reload.revision) == 0) {
78
- setTimeout(() => {
79
- handleReload();
80
- }, Number(reload === null || reload === void 0 ? void 0 : reload.revision));
81
- }
82
- }, [displayed._rev, reload === null || reload === void 0 ? void 0 : reload.revision]);
83
-
84
- // Set initial URL and refresh on new revisions
85
- (0, _react.useEffect)(() => {
86
- var getUrl = /*#__PURE__*/function () {
87
- var _ref = _asyncToGenerator(function* () {
88
- var resolveUrl = typeof url === 'function' ? yield url(displayed) : "";
89
-
90
- // Only update state if URL has changed
91
- if (resolveUrl !== displayUrl) {
92
- setDisplayUrl(resolveUrl);
93
- }
94
- });
95
- return function getUrl() {
96
- return _ref.apply(this, arguments);
97
- };
98
- }();
99
- if (typeof url === 'function') {
100
- getUrl();
101
- }
102
- // eslint-disable-next-line react-hooks/exhaustive-deps
103
- }, [displayed._rev]);
104
- if (!displayUrl || typeof displayUrl !== 'string') {
105
- return /*#__PURE__*/_react.default.createElement(_ui.ThemeProvider, null, /*#__PURE__*/_react.default.createElement(_ui.Flex, {
106
- padding: 5,
107
- items: "center",
108
- justify: "center"
109
- }, /*#__PURE__*/_react.default.createElement(_ui.Spinner, null)));
110
- }
111
- return /*#__PURE__*/_react.default.createElement(_ui.ThemeProvider, null, /*#__PURE__*/_react.default.createElement("textarea", {
112
- style: {
113
- position: "absolute",
114
- pointerEvents: "none",
115
- opacity: 0
116
- },
117
- ref: input,
118
- value: displayUrl,
119
- readOnly: true,
120
- tabIndex: -1
121
- }), /*#__PURE__*/_react.default.createElement(_ui.Flex, {
122
- direction: "column",
123
- style: {
124
- height: "100%"
125
- }
126
- }, /*#__PURE__*/_react.default.createElement(_ui.Card, {
127
- padding: 2,
128
- borderBottom: 1
129
- }, /*#__PURE__*/_react.default.createElement(_ui.Flex, {
130
- align: "center",
131
- gap: 2
132
- }, /*#__PURE__*/_react.default.createElement(_ui.Flex, {
133
- align: "center",
134
- gap: 1
135
- }, /*#__PURE__*/_react.default.createElement(_ui.Button, {
136
- fontSize: [1],
137
- padding: 2,
138
- tone: "primary",
139
- mode: iframeSize === 'mobile' ? 'default' : 'ghost',
140
- icon: _icons.MobileDeviceIcon,
141
- onClick: () => setIframeSize(iframeSize === 'mobile' ? 'desktop' : 'mobile')
142
- })), /*#__PURE__*/_react.default.createElement(_ui.Box, {
143
- flex: 1
144
- }, /*#__PURE__*/_react.default.createElement(_ui.Text, {
145
- size: 0,
146
- textOverflow: "ellipsis"
147
- }, displayUrl)), /*#__PURE__*/_react.default.createElement(_ui.Flex, {
148
- align: "center",
149
- gap: 1
150
- }, reload !== null && reload !== void 0 && reload.button ? /*#__PURE__*/_react.default.createElement(_ui.Button, {
151
- fontSize: [1],
152
- padding: 2,
153
- icon: _icons.UndoIcon,
154
- title: "Reload",
155
- "aria-label": "Reload",
156
- onClick: () => handleReload()
157
- }) : null, /*#__PURE__*/_react.default.createElement(_ui.Button, {
158
- fontSize: [1],
159
- icon: _icons.CopyIcon,
160
- padding: [2],
161
- title: "Copy",
162
- "aria-label": "Copy",
163
- onClick: () => handleCopy()
164
- }), /*#__PURE__*/_react.default.createElement(_ui.Button, {
165
- fontSize: [1],
166
- icon: _icons.LeaveIcon,
167
- padding: [2],
168
- text: "Open",
169
- tone: "primary",
170
- onClick: () => window.open(displayUrl)
171
- })))), /*#__PURE__*/_react.default.createElement(_ui.Card, {
172
- tone: "transparent",
173
- padding: iframeSize === 'mobile' ? 2 : 0,
174
- style: {
175
- height: "100%"
176
- }
177
- }, /*#__PURE__*/_react.default.createElement(_ui.Flex, {
178
- align: "center",
179
- justify: "center",
180
- style: {
181
- height: "100%"
182
- }
183
- }, /*#__PURE__*/_react.default.createElement("iframe", _extends({
184
- ref: iframe,
185
- title: "preview",
186
- style: sizes[iframeSize],
187
- frameBorder: "0",
188
- src: displayUrl
189
- }, attributes))))));
190
- }
191
- var _default = Iframe;
192
- exports.default = _default;
193
- //# sourceMappingURL=Iframe.js.map
package/lib/Iframe.js.map DELETED
@@ -1 +0,0 @@
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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"}
@@ -1,50 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
- var _react = require("react");
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); } }
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); }); }; }
10
- function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
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."); }
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); }
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; }
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; }
15
- function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
16
- // Return success
17
-
18
- function useCopyToClipboard() {
19
- var _useState = (0, _react.useState)(null),
20
- _useState2 = _slicedToArray(_useState, 2),
21
- copiedText = _useState2[0],
22
- setCopiedText = _useState2[1];
23
- var copy = /*#__PURE__*/function () {
24
- var _ref = _asyncToGenerator(function* (text) {
25
- var _navigator;
26
- if (!((_navigator = navigator) !== null && _navigator !== void 0 && _navigator.clipboard)) {
27
- console.warn('Clipboard not supported');
28
- return false;
29
- }
30
-
31
- // Try to save to clipboard then save it in the state if worked
32
- try {
33
- yield navigator.clipboard.writeText(text);
34
- setCopiedText(text);
35
- return true;
36
- } catch (error) {
37
- console.warn('Copy failed', error);
38
- setCopiedText(null);
39
- return false;
40
- }
41
- });
42
- return function copy(_x) {
43
- return _ref.apply(this, arguments);
44
- };
45
- }();
46
- return [copiedText, copy];
47
- }
48
- var _default = useCopyToClipboard;
49
- exports.default = _default;
50
- //# sourceMappingURL=useCopytoClipboard.js.map
@@ -1 +0,0 @@
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"}
@@ -1,30 +0,0 @@
1
- import {useState} from 'react'
2
-
3
- type CopiedValue = string | null
4
- type CopyFn = (text: string) => Promise<boolean> // Return success
5
-
6
- function useCopyToClipboard(): [CopiedValue, CopyFn] {
7
- const [copiedText, setCopiedText] = useState<CopiedValue>(null)
8
-
9
- const copy: CopyFn = async (text) => {
10
- if (!navigator?.clipboard) {
11
- console.warn('Clipboard not supported')
12
- return false
13
- }
14
-
15
- // Try to save to clipboard then save it in the state if worked
16
- try {
17
- await navigator.clipboard.writeText(text)
18
- setCopiedText(text)
19
- return true
20
- } catch (error) {
21
- console.warn('Copy failed', error)
22
- setCopiedText(null)
23
- return false
24
- }
25
- }
26
-
27
- return [copiedText, copy]
28
- }
29
-
30
- export default useCopyToClipboard