@willbooster/react-frame-component 0.0.0-semantically-released

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.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Ryan Seddon
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,174 @@
1
+ # React <Frame /> component
2
+
3
+ [![Test](https://github.com/WillBooster/react-frame-component/actions/workflows/test.yml/badge.svg)](https://github.com/WillBooster/react-frame-component/actions/workflows/test.yml)
4
+ [![Deploy example](https://github.com/WillBooster/react-frame-component/actions/workflows/deploy-example.yml/badge.svg)](https://github.com/WillBooster/react-frame-component/actions/workflows/deploy-example.yml)
5
+ [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
6
+ [![NPM version][npm-image]][npm-url]
7
+
8
+ This component allows you to encapsulate your entire React application or per component in an iFrame.
9
+
10
+ This is a fork of [ryanseddon/react-frame-component](https://github.com/ryanseddon/react-frame-component) maintained by [WillBooster](https://github.com/WillBooster).
11
+
12
+ ```bash
13
+ npm install --save @willbooster/react-frame-component
14
+ ```
15
+
16
+ ## How to use:
17
+
18
+ ```js
19
+ import Frame from '@willbooster/react-frame-component';
20
+ ```
21
+
22
+ Go check out the [demo][demo-url].
23
+
24
+ ```jsx
25
+ const Header = ({ children }) => (
26
+ <Frame>
27
+ <h1>{children}</h1>
28
+ </Frame>
29
+ );
30
+
31
+ ReactDOM.render(<Header>Hello</Header>, document.body);
32
+ ```
33
+
34
+ Or you can wrap it at the `render` call.
35
+
36
+ ```jsx
37
+ ReactDOM.render(
38
+ <Frame>
39
+ <Header>Hello</Header>
40
+ </Frame>,
41
+ document.body
42
+ );
43
+ ```
44
+
45
+ ##### Props:
46
+
47
+ ###### head
48
+
49
+ `head: PropTypes.node`
50
+
51
+ The `head` prop is a dom node that gets inserted before the children of the frame. Note that this is injected into the body of frame (see the blog post for why). This has the benefit of being able to update and works for stylesheets.
52
+
53
+ ###### initialContent
54
+
55
+ `initialContent: PropTypes.string`
56
+
57
+ Defaults to `'<!DOCTYPE html><html><head></head><body><div></div></body></html>'`
58
+
59
+ The `initialContent` props is the initial html injected into frame. It is only injected once, but allows you to insert any html into the frame (e.g. a head tag, script tags, etc). Note that it does _not_ update if you change the prop. Also at least one div is required in the body of the html, which we use to render the react dom into.
60
+
61
+ ###### mountTarget
62
+
63
+ `mountTarget: PropTypes.string`
64
+
65
+ The `mountTarget` props is a css selector (#target/.target) that specifies where in the `initialContent` of the iframe, children will be mounted.
66
+
67
+ ```jsx
68
+ <Frame
69
+ initialContent='<!DOCTYPE html><html><head></head><body><h1>i wont be changed</h1><div id="mountHere"></div></body></html>'
70
+ mountTarget="#mountHere"
71
+ ></Frame>
72
+ ```
73
+
74
+ ###### dangerouslyUseDocWrite
75
+
76
+ `dangerouslyUseDocWrite: PropTypes.bool`
77
+
78
+ Defaults to `false`
79
+
80
+ The frame's initial content, as defined by the `initialContent` prop, is populated via the frame's `srcdoc` attribute by default. However, this can cause issues with some libraries such as Recaptcha and Google Maps that depend on the frame's location/origin. In these cases, setting this flag will cause `Frame` to use `document.write()` to populate the initial content. This is **unperformant and unrecommended**, but allows these libraries to be used inside a `Frame` instance.
81
+
82
+ ###### contentDidMount and contentDidUpdate
83
+
84
+ `contentDidMount: PropTypes.func`
85
+ `contentDidUpdate: PropTypes.func`
86
+
87
+ `contentDidMount` and `contentDidUpdate` are conceptually equivalent to
88
+ `componentDidMount` and `componentDidUpdate`, respectively. The reason these are
89
+ needed is because internally we call `ReactDOM.render` which starts a new set of
90
+ lifecycle calls. This set of lifecycle calls are sometimes triggered after the
91
+ lifecycle of the parent component, so these callbacks provide a hook to know
92
+ when the frame contents are mounted and updated.
93
+
94
+ ###### ref
95
+
96
+ `ref: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ current: PropTypes.instanceOf(Element) }) ])`
97
+
98
+ The `ref` prop provides a way to access inner iframe DOM node. To utilitize this prop use, for example, one of the React's built-in methods to create a ref: [`React.createRef()`](https://reactjs.org/docs/refs-and-the-dom.html#creating-refs) or [`React.useRef()`](https://reactjs.org/docs/hooks-reference.html#useref).
99
+
100
+ ```js
101
+ const MyComponent = (props) => {
102
+ const iframeRef = React.useRef();
103
+
104
+ React.useEffect(() => {
105
+ // Use iframeRef for:
106
+ // - focus managing
107
+ // - triggering imperative animations
108
+ // - integrating with third-party DOM libraries
109
+ iframeRef.current.focus();
110
+ }, []);
111
+
112
+ return (
113
+ <Frame ref={iframeRef}>
114
+ <InnerComponent />
115
+ </Frame>
116
+ );
117
+ };
118
+ ```
119
+
120
+ ##### Accessing the iframe's window and document
121
+
122
+ The iframe's `window` and `document` may be accessed via the `FrameContextConsumer` or the `useFrame` hook.
123
+
124
+ The example with `FrameContextConsumer`:
125
+
126
+ ```js
127
+ import Frame, { FrameContextConsumer } from '@willbooster/react-frame-component';
128
+
129
+ const MyComponent = (props, context) => (
130
+ <Frame>
131
+ <FrameContextConsumer>
132
+ {
133
+ // Callback is invoked with iframe's window and document instances
134
+ ({ document, window }) => {
135
+ // Render Children
136
+ }
137
+ }
138
+ </FrameContextConsumer>
139
+ </Frame>
140
+ );
141
+ ```
142
+
143
+ The example with `useFrame` hook:
144
+
145
+ ```js
146
+ import Frame, { useFrame } from '@willbooster/react-frame-component';
147
+
148
+ const InnerComponent = () => {
149
+ // Hook returns iframe's window and document instances from Frame context
150
+ const { document, window } = useFrame();
151
+
152
+ return null;
153
+ };
154
+
155
+ const OuterComponent = () => (
156
+ <Frame>
157
+ <InnerComponent />
158
+ </Frame>
159
+ );
160
+ ```
161
+
162
+ ## More info
163
+
164
+ I wrote a [blog post][blog-url] about building this component.
165
+
166
+ ## License
167
+
168
+ Copyright 2014, Ryan Seddon.
169
+ This content is released under the MIT license http://ryanseddon.mit-license.org
170
+
171
+ [npm-url]: https://www.npmjs.com/package/@willbooster/react-frame-component
172
+ [npm-image]: https://img.shields.io/npm/v/%40willbooster%2Freact-frame-component
173
+ [demo-url]: https://willbooster.github.io/react-frame-component/
174
+ [blog-url]: https://medium.com/@ryanseddon/rendering-to-iframes-in-react-d1cb92274f86
@@ -0,0 +1,151 @@
1
+ import React, { Children, Component } from "react";
2
+ import ReactDOM from "react-dom";
3
+ import PropTypes from "prop-types";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region src/Context.jsx
6
+ var doc;
7
+ var win;
8
+ if (typeof document !== "undefined") doc = document;
9
+ if (globalThis.window !== void 0) win = globalThis.window;
10
+ var FrameContext = React.createContext({
11
+ document: doc,
12
+ window: win
13
+ });
14
+ var useFrame = () => React.useContext(FrameContext);
15
+ var { Provider: FrameContextProvider, Consumer: FrameContextConsumer } = FrameContext;
16
+ //#endregion
17
+ //#region src/Content.jsx
18
+ var Content = class extends Component {
19
+ static propTypes = {
20
+ children: PropTypes.element.isRequired,
21
+ contentDidMount: PropTypes.func.isRequired,
22
+ contentDidUpdate: PropTypes.func.isRequired
23
+ };
24
+ componentDidMount() {
25
+ this.props.contentDidMount();
26
+ }
27
+ componentDidUpdate() {
28
+ this.props.contentDidUpdate();
29
+ }
30
+ render() {
31
+ return Children.only(this.props.children);
32
+ }
33
+ };
34
+ //#endregion
35
+ //#region src/Frame.jsx
36
+ var Frame = class extends Component {
37
+ static propTypes = {
38
+ style: PropTypes.object,
39
+ head: PropTypes.node,
40
+ initialContent: PropTypes.string,
41
+ mountTarget: PropTypes.string,
42
+ dangerouslyUseDocWrite: PropTypes.bool,
43
+ contentDidMount: PropTypes.func,
44
+ contentDidUpdate: PropTypes.func,
45
+ children: PropTypes.oneOfType([PropTypes.element, PropTypes.arrayOf(PropTypes.element)])
46
+ };
47
+ static defaultProps = {
48
+ style: {},
49
+ head: void 0,
50
+ children: void 0,
51
+ mountTarget: void 0,
52
+ dangerouslyUseDocWrite: false,
53
+ contentDidMount: () => {},
54
+ contentDidUpdate: () => {},
55
+ initialContent: "<!DOCTYPE html><html><head></head><body><div class=\"frame-root\"></div></body></html>"
56
+ };
57
+ constructor(props, context) {
58
+ super(props, context);
59
+ this._isMounted = false;
60
+ this.nodeRef = React.createRef();
61
+ this.state = { iframeLoaded: false };
62
+ }
63
+ componentDidMount() {
64
+ this._isMounted = true;
65
+ if (this.getDoc()) this.nodeRef.current.contentWindow.addEventListener("DOMContentLoaded", this.handleLoad);
66
+ if (this.props.dangerouslyUseDocWrite) this.handleLoad();
67
+ }
68
+ componentWillUnmount() {
69
+ this._isMounted = false;
70
+ this.nodeRef.current.removeEventListener("DOMContentLoaded", this.handleLoad);
71
+ }
72
+ getDoc() {
73
+ return this.nodeRef.current ? this.nodeRef.current.contentDocument : void 0;
74
+ }
75
+ getMountTarget() {
76
+ const doc = this.getDoc();
77
+ if (!doc || !doc.body) return;
78
+ if (this.props.mountTarget) return doc.querySelector(this.props.mountTarget);
79
+ return doc.body.children[0];
80
+ }
81
+ setRef = (node) => {
82
+ this.nodeRef.current = node;
83
+ const { forwardedRef } = this.props;
84
+ if (typeof forwardedRef === "function") forwardedRef(node);
85
+ else if (forwardedRef) forwardedRef.current = node;
86
+ };
87
+ handleLoad = () => {
88
+ clearInterval(this.loadCheck);
89
+ if (!this.state.iframeLoaded) this.setState({ iframeLoaded: true });
90
+ };
91
+ loadCheck = () => setInterval(() => {
92
+ this.handleLoad();
93
+ }, 500);
94
+ renderFrameContents() {
95
+ if (!this._isMounted) return;
96
+ const doc = this.getDoc();
97
+ if (!doc) return;
98
+ const contentDidMount = this.props.contentDidMount;
99
+ const contentDidUpdate = this.props.contentDidUpdate;
100
+ const contents = /* @__PURE__ */ jsx(Content, {
101
+ contentDidMount,
102
+ contentDidUpdate,
103
+ children: /* @__PURE__ */ jsx(FrameContextProvider, {
104
+ value: {
105
+ document: doc,
106
+ window: doc.defaultView || doc.parentView
107
+ },
108
+ children: /* @__PURE__ */ jsx("div", {
109
+ className: "frame-content",
110
+ children: this.props.children
111
+ })
112
+ })
113
+ });
114
+ if (this.props.dangerouslyUseDocWrite && doc.body.children.length === 0) {
115
+ doc.open("text/html", "replace");
116
+ doc.write(this.props.initialContent);
117
+ doc.close();
118
+ }
119
+ const mountTarget = this.getMountTarget();
120
+ if (!mountTarget) return;
121
+ return [ReactDOM.createPortal(this.props.head, this.getDoc().head), ReactDOM.createPortal(contents, mountTarget)];
122
+ }
123
+ render() {
124
+ const props = {
125
+ ...this.props,
126
+ children: void 0
127
+ };
128
+ if (!this.props.dangerouslyUseDocWrite) props.srcDoc = this.props.initialContent;
129
+ delete props.head;
130
+ delete props.initialContent;
131
+ delete props.mountTarget;
132
+ delete props.dangerouslyUseDocWrite;
133
+ delete props.contentDidMount;
134
+ delete props.contentDidUpdate;
135
+ delete props.forwardedRef;
136
+ return /* @__PURE__ */ jsx("iframe", {
137
+ ...props,
138
+ ref: this.setRef,
139
+ onLoad: this.handleLoad,
140
+ children: this.state.iframeLoaded && this.renderFrameContents()
141
+ });
142
+ }
143
+ };
144
+ var Frame_default = React.forwardRef((props, ref) => /* @__PURE__ */ jsx(Frame, {
145
+ ...props,
146
+ forwardedRef: ref
147
+ }));
148
+ //#endregion
149
+ export { FrameContext, FrameContextConsumer, Frame_default as default, useFrame };
150
+
151
+ //# sourceMappingURL=react-frame-component.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-frame-component.esm.js","names":[],"sources":["../src/Context.jsx","../src/Content.jsx","../src/Frame.jsx"],"sourcesContent":["import React from 'react';\n\nlet doc;\nlet win;\nif (typeof document !== 'undefined') {\n doc = document;\n}\nif (globalThis.window !== undefined) {\n win = globalThis.window;\n}\n\nexport const FrameContext = React.createContext({ document: doc, window: win });\n\nexport const useFrame = () => React.useContext(FrameContext);\n\nexport const { Provider: FrameContextProvider, Consumer: FrameContextConsumer } = FrameContext;\n","import React, { Component, Children } from 'react'; // eslint-disable-line no-unused-vars\nimport PropTypes from 'prop-types';\n\nexport default class Content extends Component {\n static propTypes = {\n children: PropTypes.element.isRequired,\n contentDidMount: PropTypes.func.isRequired,\n contentDidUpdate: PropTypes.func.isRequired,\n };\n\n componentDidMount() {\n this.props.contentDidMount();\n }\n\n componentDidUpdate() {\n this.props.contentDidUpdate();\n }\n\n render() {\n return Children.only(this.props.children);\n }\n}\n","import React, { Component } from 'react';\nimport ReactDOM from 'react-dom';\nimport PropTypes from 'prop-types';\nimport { FrameContextProvider } from './Context';\nimport Content from './Content';\n\nexport class Frame extends Component {\n // React warns when you render directly into the body since browser extensions\n // also inject into the body and can mess up React. For this reason\n // initialContent is expected to have a div inside of the body\n // element that we render react into.\n static propTypes = {\n style: PropTypes.object,\n head: PropTypes.node,\n initialContent: PropTypes.string,\n mountTarget: PropTypes.string,\n dangerouslyUseDocWrite: PropTypes.bool,\n contentDidMount: PropTypes.func,\n contentDidUpdate: PropTypes.func,\n children: PropTypes.oneOfType([PropTypes.element, PropTypes.arrayOf(PropTypes.element)]),\n };\n\n static defaultProps = {\n style: {},\n head: undefined,\n children: undefined,\n mountTarget: undefined,\n dangerouslyUseDocWrite: false,\n contentDidMount: () => {},\n contentDidUpdate: () => {},\n initialContent: '<!DOCTYPE html><html><head></head><body><div class=\"frame-root\"></div></body></html>',\n };\n\n constructor(props, context) {\n super(props, context);\n this._isMounted = false;\n this.nodeRef = React.createRef();\n this.state = { iframeLoaded: false };\n }\n\n componentDidMount() {\n this._isMounted = true;\n\n const doc = this.getDoc();\n\n if (doc) {\n this.nodeRef.current.contentWindow.addEventListener('DOMContentLoaded', this.handleLoad);\n }\n\n if (this.props.dangerouslyUseDocWrite) {\n this.handleLoad();\n }\n }\n\n componentWillUnmount() {\n this._isMounted = false;\n\n this.nodeRef.current.removeEventListener('DOMContentLoaded', this.handleLoad);\n }\n\n getDoc() {\n return this.nodeRef.current ? this.nodeRef.current.contentDocument : undefined;\n }\n\n getMountTarget() {\n const doc = this.getDoc();\n\n if (!doc || !doc.body) {\n return;\n }\n\n if (this.props.mountTarget) {\n return doc.querySelector(this.props.mountTarget);\n }\n\n return doc.body.children[0];\n }\n\n setRef = (node) => {\n this.nodeRef.current = node;\n\n const { forwardedRef } = this.props;\n if (typeof forwardedRef === 'function') {\n forwardedRef(node);\n } else if (forwardedRef) {\n forwardedRef.current = node;\n }\n };\n\n handleLoad = () => {\n clearInterval(this.loadCheck);\n // Bail update as some browsers will trigger on both DOMContentLoaded & onLoad ala firefox\n if (!this.state.iframeLoaded) {\n this.setState({ iframeLoaded: true });\n }\n };\n\n // In certain situations on a cold cache DOMContentLoaded never gets called\n // fallback to an interval to check if that's the case\n loadCheck = () =>\n setInterval(() => {\n this.handleLoad();\n }, 500);\n\n renderFrameContents() {\n if (!this._isMounted) {\n return;\n }\n\n const doc = this.getDoc();\n\n if (!doc) {\n return;\n }\n\n const contentDidMount = this.props.contentDidMount;\n const contentDidUpdate = this.props.contentDidUpdate;\n\n const win = doc.defaultView || doc.parentView;\n const contents = (\n <Content contentDidMount={contentDidMount} contentDidUpdate={contentDidUpdate}>\n <FrameContextProvider value={{ document: doc, window: win }}>\n <div className=\"frame-content\">{this.props.children}</div>\n </FrameContextProvider>\n </Content>\n );\n\n if (this.props.dangerouslyUseDocWrite && doc.body.children.length === 0) {\n doc.open('text/html', 'replace');\n doc.write(this.props.initialContent);\n doc.close();\n }\n\n const mountTarget = this.getMountTarget();\n\n if (!mountTarget) {\n return;\n }\n\n return [ReactDOM.createPortal(this.props.head, this.getDoc().head), ReactDOM.createPortal(contents, mountTarget)];\n }\n\n render() {\n const props = {\n ...this.props,\n children: undefined, // The iframe isn't ready so we drop children from props here. #12, #17\n };\n\n if (!this.props.dangerouslyUseDocWrite) {\n props.srcDoc = this.props.initialContent;\n }\n\n delete props.head;\n delete props.initialContent;\n delete props.mountTarget;\n delete props.dangerouslyUseDocWrite;\n delete props.contentDidMount;\n delete props.contentDidUpdate;\n delete props.forwardedRef;\n\n return (\n // oxlint-disable-next-line jsx-a11y/iframe-has-title -- consumers can pass `title` via the props spread\n <iframe {...props} ref={this.setRef} onLoad={this.handleLoad}>\n {this.state.iframeLoaded && this.renderFrameContents()}\n </iframe>\n );\n }\n}\n\nexport default React.forwardRef((props, ref) => <Frame {...props} forwardedRef={ref} />);\n"],"mappings":"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"}
@@ -0,0 +1,189 @@
1
+ (function(global, factory) {
2
+ typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("react"), require("react-dom"), require("prop-types"), require("react/jsx-runtime")) : typeof define === "function" && define.amd ? define([
3
+ "exports",
4
+ "react",
5
+ "react-dom",
6
+ "prop-types",
7
+ "react/jsx-runtime"
8
+ ], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.ReactFrameComponent = {}, global.React, global.ReactDOM, global.PropTypes, global["react/jsx-runtime"]));
9
+ })(this, function(exports, react, react_dom, prop_types, react_jsx_runtime) {
10
+ Object.defineProperties(exports, {
11
+ __esModule: { value: true },
12
+ [Symbol.toStringTag]: { value: "Module" }
13
+ });
14
+ //#region \0rolldown/runtime.js
15
+ var __create = Object.create;
16
+ var __defProp = Object.defineProperty;
17
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
18
+ var __getOwnPropNames = Object.getOwnPropertyNames;
19
+ var __getProtoOf = Object.getPrototypeOf;
20
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
21
+ var __copyProps = (to, from, except, desc) => {
22
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
23
+ key = keys[i];
24
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
25
+ get: ((k) => from[k]).bind(null, key),
26
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
27
+ });
28
+ }
29
+ return to;
30
+ };
31
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
32
+ value: mod,
33
+ enumerable: true
34
+ }) : target, mod));
35
+ //#endregion
36
+ react = __toESM(react, 1);
37
+ react_dom = __toESM(react_dom, 1);
38
+ prop_types = __toESM(prop_types, 1);
39
+ //#region src/Context.jsx
40
+ var doc;
41
+ var win;
42
+ if (typeof document !== "undefined") doc = document;
43
+ if (globalThis.window !== void 0) win = globalThis.window;
44
+ var FrameContext = react.default.createContext({
45
+ document: doc,
46
+ window: win
47
+ });
48
+ var useFrame = () => react.default.useContext(FrameContext);
49
+ var { Provider: FrameContextProvider, Consumer: FrameContextConsumer } = FrameContext;
50
+ //#endregion
51
+ //#region src/Content.jsx
52
+ var Content = class extends react.Component {
53
+ static propTypes = {
54
+ children: prop_types.default.element.isRequired,
55
+ contentDidMount: prop_types.default.func.isRequired,
56
+ contentDidUpdate: prop_types.default.func.isRequired
57
+ };
58
+ componentDidMount() {
59
+ this.props.contentDidMount();
60
+ }
61
+ componentDidUpdate() {
62
+ this.props.contentDidUpdate();
63
+ }
64
+ render() {
65
+ return react.Children.only(this.props.children);
66
+ }
67
+ };
68
+ //#endregion
69
+ //#region src/Frame.jsx
70
+ var Frame = class extends react.Component {
71
+ static propTypes = {
72
+ style: prop_types.default.object,
73
+ head: prop_types.default.node,
74
+ initialContent: prop_types.default.string,
75
+ mountTarget: prop_types.default.string,
76
+ dangerouslyUseDocWrite: prop_types.default.bool,
77
+ contentDidMount: prop_types.default.func,
78
+ contentDidUpdate: prop_types.default.func,
79
+ children: prop_types.default.oneOfType([prop_types.default.element, prop_types.default.arrayOf(prop_types.default.element)])
80
+ };
81
+ static defaultProps = {
82
+ style: {},
83
+ head: void 0,
84
+ children: void 0,
85
+ mountTarget: void 0,
86
+ dangerouslyUseDocWrite: false,
87
+ contentDidMount: () => {},
88
+ contentDidUpdate: () => {},
89
+ initialContent: "<!DOCTYPE html><html><head></head><body><div class=\"frame-root\"></div></body></html>"
90
+ };
91
+ constructor(props, context) {
92
+ super(props, context);
93
+ this._isMounted = false;
94
+ this.nodeRef = react.default.createRef();
95
+ this.state = { iframeLoaded: false };
96
+ }
97
+ componentDidMount() {
98
+ this._isMounted = true;
99
+ if (this.getDoc()) this.nodeRef.current.contentWindow.addEventListener("DOMContentLoaded", this.handleLoad);
100
+ if (this.props.dangerouslyUseDocWrite) this.handleLoad();
101
+ }
102
+ componentWillUnmount() {
103
+ this._isMounted = false;
104
+ this.nodeRef.current.removeEventListener("DOMContentLoaded", this.handleLoad);
105
+ }
106
+ getDoc() {
107
+ return this.nodeRef.current ? this.nodeRef.current.contentDocument : void 0;
108
+ }
109
+ getMountTarget() {
110
+ const doc = this.getDoc();
111
+ if (!doc || !doc.body) return;
112
+ if (this.props.mountTarget) return doc.querySelector(this.props.mountTarget);
113
+ return doc.body.children[0];
114
+ }
115
+ setRef = (node) => {
116
+ this.nodeRef.current = node;
117
+ const { forwardedRef } = this.props;
118
+ if (typeof forwardedRef === "function") forwardedRef(node);
119
+ else if (forwardedRef) forwardedRef.current = node;
120
+ };
121
+ handleLoad = () => {
122
+ clearInterval(this.loadCheck);
123
+ if (!this.state.iframeLoaded) this.setState({ iframeLoaded: true });
124
+ };
125
+ loadCheck = () => setInterval(() => {
126
+ this.handleLoad();
127
+ }, 500);
128
+ renderFrameContents() {
129
+ if (!this._isMounted) return;
130
+ const doc = this.getDoc();
131
+ if (!doc) return;
132
+ const contentDidMount = this.props.contentDidMount;
133
+ const contentDidUpdate = this.props.contentDidUpdate;
134
+ const contents = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Content, {
135
+ contentDidMount,
136
+ contentDidUpdate,
137
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FrameContextProvider, {
138
+ value: {
139
+ document: doc,
140
+ window: doc.defaultView || doc.parentView
141
+ },
142
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
143
+ className: "frame-content",
144
+ children: this.props.children
145
+ })
146
+ })
147
+ });
148
+ if (this.props.dangerouslyUseDocWrite && doc.body.children.length === 0) {
149
+ doc.open("text/html", "replace");
150
+ doc.write(this.props.initialContent);
151
+ doc.close();
152
+ }
153
+ const mountTarget = this.getMountTarget();
154
+ if (!mountTarget) return;
155
+ return [react_dom.default.createPortal(this.props.head, this.getDoc().head), react_dom.default.createPortal(contents, mountTarget)];
156
+ }
157
+ render() {
158
+ const props = {
159
+ ...this.props,
160
+ children: void 0
161
+ };
162
+ if (!this.props.dangerouslyUseDocWrite) props.srcDoc = this.props.initialContent;
163
+ delete props.head;
164
+ delete props.initialContent;
165
+ delete props.mountTarget;
166
+ delete props.dangerouslyUseDocWrite;
167
+ delete props.contentDidMount;
168
+ delete props.contentDidUpdate;
169
+ delete props.forwardedRef;
170
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("iframe", {
171
+ ...props,
172
+ ref: this.setRef,
173
+ onLoad: this.handleLoad,
174
+ children: this.state.iframeLoaded && this.renderFrameContents()
175
+ });
176
+ }
177
+ };
178
+ var Frame_default = react.default.forwardRef((props, ref) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Frame, {
179
+ ...props,
180
+ forwardedRef: ref
181
+ }));
182
+ //#endregion
183
+ exports.FrameContext = FrameContext;
184
+ exports.FrameContextConsumer = FrameContextConsumer;
185
+ exports.default = Frame_default;
186
+ exports.useFrame = useFrame;
187
+ });
188
+
189
+ //# sourceMappingURL=react-frame-component.umd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-frame-component.umd.js","names":[],"sources":["../src/Context.jsx","../src/Content.jsx","../src/Frame.jsx"],"sourcesContent":["import React from 'react';\n\nlet doc;\nlet win;\nif (typeof document !== 'undefined') {\n doc = document;\n}\nif (globalThis.window !== undefined) {\n win = globalThis.window;\n}\n\nexport const FrameContext = React.createContext({ document: doc, window: win });\n\nexport const useFrame = () => React.useContext(FrameContext);\n\nexport const { Provider: FrameContextProvider, Consumer: FrameContextConsumer } = FrameContext;\n","import React, { Component, Children } from 'react'; // eslint-disable-line no-unused-vars\nimport PropTypes from 'prop-types';\n\nexport default class Content extends Component {\n static propTypes = {\n children: PropTypes.element.isRequired,\n contentDidMount: PropTypes.func.isRequired,\n contentDidUpdate: PropTypes.func.isRequired,\n };\n\n componentDidMount() {\n this.props.contentDidMount();\n }\n\n componentDidUpdate() {\n this.props.contentDidUpdate();\n }\n\n render() {\n return Children.only(this.props.children);\n }\n}\n","import React, { Component } from 'react';\nimport ReactDOM from 'react-dom';\nimport PropTypes from 'prop-types';\nimport { FrameContextProvider } from './Context';\nimport Content from './Content';\n\nexport class Frame extends Component {\n // React warns when you render directly into the body since browser extensions\n // also inject into the body and can mess up React. For this reason\n // initialContent is expected to have a div inside of the body\n // element that we render react into.\n static propTypes = {\n style: PropTypes.object,\n head: PropTypes.node,\n initialContent: PropTypes.string,\n mountTarget: PropTypes.string,\n dangerouslyUseDocWrite: PropTypes.bool,\n contentDidMount: PropTypes.func,\n contentDidUpdate: PropTypes.func,\n children: PropTypes.oneOfType([PropTypes.element, PropTypes.arrayOf(PropTypes.element)]),\n };\n\n static defaultProps = {\n style: {},\n head: undefined,\n children: undefined,\n mountTarget: undefined,\n dangerouslyUseDocWrite: false,\n contentDidMount: () => {},\n contentDidUpdate: () => {},\n initialContent: '<!DOCTYPE html><html><head></head><body><div class=\"frame-root\"></div></body></html>',\n };\n\n constructor(props, context) {\n super(props, context);\n this._isMounted = false;\n this.nodeRef = React.createRef();\n this.state = { iframeLoaded: false };\n }\n\n componentDidMount() {\n this._isMounted = true;\n\n const doc = this.getDoc();\n\n if (doc) {\n this.nodeRef.current.contentWindow.addEventListener('DOMContentLoaded', this.handleLoad);\n }\n\n if (this.props.dangerouslyUseDocWrite) {\n this.handleLoad();\n }\n }\n\n componentWillUnmount() {\n this._isMounted = false;\n\n this.nodeRef.current.removeEventListener('DOMContentLoaded', this.handleLoad);\n }\n\n getDoc() {\n return this.nodeRef.current ? this.nodeRef.current.contentDocument : undefined;\n }\n\n getMountTarget() {\n const doc = this.getDoc();\n\n if (!doc || !doc.body) {\n return;\n }\n\n if (this.props.mountTarget) {\n return doc.querySelector(this.props.mountTarget);\n }\n\n return doc.body.children[0];\n }\n\n setRef = (node) => {\n this.nodeRef.current = node;\n\n const { forwardedRef } = this.props;\n if (typeof forwardedRef === 'function') {\n forwardedRef(node);\n } else if (forwardedRef) {\n forwardedRef.current = node;\n }\n };\n\n handleLoad = () => {\n clearInterval(this.loadCheck);\n // Bail update as some browsers will trigger on both DOMContentLoaded & onLoad ala firefox\n if (!this.state.iframeLoaded) {\n this.setState({ iframeLoaded: true });\n }\n };\n\n // In certain situations on a cold cache DOMContentLoaded never gets called\n // fallback to an interval to check if that's the case\n loadCheck = () =>\n setInterval(() => {\n this.handleLoad();\n }, 500);\n\n renderFrameContents() {\n if (!this._isMounted) {\n return;\n }\n\n const doc = this.getDoc();\n\n if (!doc) {\n return;\n }\n\n const contentDidMount = this.props.contentDidMount;\n const contentDidUpdate = this.props.contentDidUpdate;\n\n const win = doc.defaultView || doc.parentView;\n const contents = (\n <Content contentDidMount={contentDidMount} contentDidUpdate={contentDidUpdate}>\n <FrameContextProvider value={{ document: doc, window: win }}>\n <div className=\"frame-content\">{this.props.children}</div>\n </FrameContextProvider>\n </Content>\n );\n\n if (this.props.dangerouslyUseDocWrite && doc.body.children.length === 0) {\n doc.open('text/html', 'replace');\n doc.write(this.props.initialContent);\n doc.close();\n }\n\n const mountTarget = this.getMountTarget();\n\n if (!mountTarget) {\n return;\n }\n\n return [ReactDOM.createPortal(this.props.head, this.getDoc().head), ReactDOM.createPortal(contents, mountTarget)];\n }\n\n render() {\n const props = {\n ...this.props,\n children: undefined, // The iframe isn't ready so we drop children from props here. #12, #17\n };\n\n if (!this.props.dangerouslyUseDocWrite) {\n props.srcDoc = this.props.initialContent;\n }\n\n delete props.head;\n delete props.initialContent;\n delete props.mountTarget;\n delete props.dangerouslyUseDocWrite;\n delete props.contentDidMount;\n delete props.contentDidUpdate;\n delete props.forwardedRef;\n\n return (\n // oxlint-disable-next-line jsx-a11y/iframe-has-title -- consumers can pass `title` via the props spread\n <iframe {...props} ref={this.setRef} onLoad={this.handleLoad}>\n {this.state.iframeLoaded && this.renderFrameContents()}\n </iframe>\n );\n }\n}\n\nexport default React.forwardRef((props, ref) => <Frame {...props} forwardedRef={ref} />);\n"],"mappings":"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"}
package/index.d.ts ADDED
@@ -0,0 +1,29 @@
1
+ import * as React from 'react';
2
+
3
+ export interface FrameComponentProps
4
+ extends React.IframeHTMLAttributes<HTMLIFrameElement>,
5
+ React.RefAttributes<HTMLIFrameElement> {
6
+ head?: React.ReactNode | undefined;
7
+ mountTarget?: string | undefined;
8
+ initialContent?: string | undefined;
9
+ contentDidMount?: (() => void) | undefined;
10
+ contentDidUpdate?: (() => void) | undefined;
11
+ dangerouslyUseDocWrite?: boolean | undefined;
12
+ children: React.ReactNode;
13
+ }
14
+
15
+ declare const FrameComponent: React.ForwardRefExoticComponent<FrameComponentProps>;
16
+ export default FrameComponent;
17
+
18
+ export interface FrameContextProps {
19
+ document?: Document;
20
+ window?: Window;
21
+ }
22
+
23
+ export declare const FrameContext: React.Context<FrameContextProps>;
24
+
25
+ export declare const FrameContextProvider: React.Provider<FrameContextProps>;
26
+
27
+ export declare const FrameContextConsumer: React.Consumer<FrameContextProps>;
28
+
29
+ export declare function useFrame(): FrameContextProps;
package/package.json ADDED
@@ -0,0 +1,93 @@
1
+ {
2
+ "name": "@willbooster/react-frame-component",
3
+ "version": "0.0.0-semantically-released",
4
+ "description": "React component to wrap your application or component in an iFrame for encapsulation purposes",
5
+ "keywords": [
6
+ "React",
7
+ "component",
8
+ "iFrame",
9
+ "browser"
10
+ ],
11
+ "homepage": "https://github.com/WillBooster/react-frame-component#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/WillBooster/react-frame-component/issues"
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/WillBooster/react-frame-component.git"
18
+ },
19
+ "license": "MIT",
20
+ "author": "WillBooster Inc.",
21
+ "contributors": [
22
+ "Chris Trevino <darthtrevino@gmail.com>"
23
+ ],
24
+ "type": "module",
25
+ "exports": {
26
+ ".": {
27
+ "types": "./index.d.ts",
28
+ "import": "./dist/react-frame-component.esm.js",
29
+ "require": "./dist/react-frame-component.umd.js"
30
+ }
31
+ },
32
+ "main": "dist/react-frame-component.umd.js",
33
+ "module": "dist/react-frame-component.esm.js",
34
+ "types": "index.d.ts",
35
+ "files": [
36
+ "dist",
37
+ "index.d.ts"
38
+ ],
39
+ "scripts": {
40
+ "build": "vite build",
41
+ "build:example": "vite build --config vite.example.config.js",
42
+ "clean": "rimraf dist",
43
+ "cleanup": "yarn format && yarn lint-fix",
44
+ "format": "sort-package-json && yarn format-code",
45
+ "format-code": "oxfmt --write --no-error-on-unmatched-pattern . '!**/package.json'",
46
+ "lint": "oxlint --no-error-on-unmatched-pattern .",
47
+ "lint-fix": "yarn lint --fix",
48
+ "prepare": "lefthook install || true",
49
+ "serve": "vite --root example",
50
+ "start": "npm run serve",
51
+ "test": "vitest run",
52
+ "test:watch": "vitest",
53
+ "test/ci-setup": "playwright install --with-deps chromium firefox",
54
+ "verify": "wb verify",
55
+ "verify-full": "wb verify --full"
56
+ },
57
+ "devDependencies": {
58
+ "@playwright/test": "^1.58.2",
59
+ "@testing-library/dom": "^10.4.1",
60
+ "@testing-library/react": "^16.3.2",
61
+ "@tsconfig/node-lts": "24.0.0",
62
+ "@tsconfig/node-ts": "23.6.4",
63
+ "@types/react": "^18",
64
+ "@vitejs/plugin-react": "^5.1.4",
65
+ "@vitest/browser": "^4.0.18",
66
+ "@vitest/browser-playwright": "^4.0.18",
67
+ "@willbooster/oxfmt-config": "1.2.2",
68
+ "@willbooster/oxlint-config": "1.4.8",
69
+ "@willbooster/wb": "13.22.19",
70
+ "conventional-changelog-conventionalcommits": "^9.3.1",
71
+ "lefthook": "2.1.9",
72
+ "oxfmt": "0.57.0",
73
+ "oxlint": "1.72.0",
74
+ "oxlint-tsgolint": "0.24.0",
75
+ "prop-types": "^15.8.1",
76
+ "react": "^18.2.0",
77
+ "react-dom": "^18.2.0",
78
+ "rimraf": "^5.0.5",
79
+ "semantic-release": "^25.0.3",
80
+ "sort-package-json": "4.0.0",
81
+ "vite": "8.1.0",
82
+ "vitest": "^4.0.18"
83
+ },
84
+ "peerDependencies": {
85
+ "prop-types": "^15.8.1 || ^16.0.0 || ^17.0.0 || ^18.0.0",
86
+ "react": ">= 16.8 || ^17.0.0 || ^18.0.0 || ^19.0.0",
87
+ "react-dom": ">= 16.8 || ^17.0.0 || ^18.0.0 || ^19.0.0"
88
+ },
89
+ "packageManager": "yarn@4.17.0",
90
+ "publishConfig": {
91
+ "access": "public"
92
+ }
93
+ }