UNPKG

react-frame-component

Version:

React component to wrap your application or component in an iFrame for encapsulation purposes

189 lines (188 loc) 6.88 kB
(function(global, factory) { 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([ "exports", "react", "react-dom", "prop-types", "react/jsx-runtime" ], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.ReactFrameComponent = {}, global.React, global.ReactDOM, global.PropTypes, global["react/jsx-runtime"])); })(this, function(exports, react, react_dom, prop_types, react_jsx_runtime) { Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } }); //#region \0rolldown/runtime.js var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) { key = keys[i]; if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: ((k) => from[k]).bind(null, key), enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); //#endregion react = __toESM(react); react_dom = __toESM(react_dom); prop_types = __toESM(prop_types); //#region src/Context.jsx var doc; var win; if (typeof document !== "undefined") doc = document; if (typeof window !== "undefined") win = window; var FrameContext = react.default.createContext({ document: doc, window: win }); var useFrame = () => react.default.useContext(FrameContext); var { Provider: FrameContextProvider, Consumer: FrameContextConsumer } = FrameContext; //#endregion //#region src/Content.jsx var Content = class extends react.Component { static propTypes = { children: prop_types.default.element.isRequired, contentDidMount: prop_types.default.func.isRequired, contentDidUpdate: prop_types.default.func.isRequired }; componentDidMount() { this.props.contentDidMount(); } componentDidUpdate() { this.props.contentDidUpdate(); } render() { return react.Children.only(this.props.children); } }; //#endregion //#region src/Frame.jsx var Frame = class extends react.Component { static propTypes = { style: prop_types.default.object, head: prop_types.default.node, initialContent: prop_types.default.string, mountTarget: prop_types.default.string, dangerouslyUseDocWrite: prop_types.default.bool, contentDidMount: prop_types.default.func, contentDidUpdate: prop_types.default.func, children: prop_types.default.oneOfType([prop_types.default.element, prop_types.default.arrayOf(prop_types.default.element)]) }; static defaultProps = { style: {}, head: null, children: void 0, mountTarget: void 0, dangerouslyUseDocWrite: false, contentDidMount: () => {}, contentDidUpdate: () => {}, initialContent: "<!DOCTYPE html><html><head></head><body><div class=\"frame-root\"></div></body></html>" }; constructor(props, context) { super(props, context); this._isMounted = false; this.nodeRef = react.default.createRef(); this.state = { iframeLoaded: false }; } componentDidMount() { this._isMounted = true; if (this.getDoc()) this.nodeRef.current.contentWindow.addEventListener("DOMContentLoaded", this.handleLoad); if (this.props.dangerouslyUseDocWrite) this.handleLoad(); } componentWillUnmount() { this._isMounted = false; this.nodeRef.current.removeEventListener("DOMContentLoaded", this.handleLoad); } getDoc() { return this.nodeRef.current ? this.nodeRef.current.contentDocument : null; } getMountTarget() { const doc = this.getDoc(); if (!doc || !doc.body) return null; if (this.props.mountTarget) return doc.querySelector(this.props.mountTarget); return doc.body.children[0]; } setRef = (node) => { this.nodeRef.current = node; const { forwardedRef } = this.props; if (typeof forwardedRef === "function") forwardedRef(node); else if (forwardedRef) forwardedRef.current = node; }; handleLoad = () => { clearInterval(this.loadCheck); if (!this.state.iframeLoaded) this.setState({ iframeLoaded: true }); }; loadCheck = () => setInterval(() => { this.handleLoad(); }, 500); renderFrameContents() { if (!this._isMounted) return null; const doc = this.getDoc(); if (!doc) return null; const contentDidMount = this.props.contentDidMount; const contentDidUpdate = this.props.contentDidUpdate; const contents = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Content, { contentDidMount, contentDidUpdate, children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FrameContextProvider, { value: { document: doc, window: doc.defaultView || doc.parentView }, children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "frame-content", children: this.props.children }) }) }); if (this.props.dangerouslyUseDocWrite && doc.body.children.length < 1) { doc.open("text/html", "replace"); doc.write(this.props.initialContent); doc.close(); } const mountTarget = this.getMountTarget(); if (!mountTarget) return null; return [react_dom.default.createPortal(this.props.head, this.getDoc().head), react_dom.default.createPortal(contents, mountTarget)]; } render() { const props = { ...this.props, children: void 0 }; if (!this.props.dangerouslyUseDocWrite) props.srcDoc = this.props.initialContent; delete props.head; delete props.initialContent; delete props.mountTarget; delete props.dangerouslyUseDocWrite; delete props.contentDidMount; delete props.contentDidUpdate; delete props.forwardedRef; return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("iframe", { ...props, ref: this.setRef, onLoad: this.handleLoad, children: this.state.iframeLoaded && this.renderFrameContents() }); } }; var Frame_default = react.default.forwardRef((props, ref) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Frame, { ...props, forwardedRef: ref })); //#endregion exports.FrameContext = FrameContext; exports.FrameContextConsumer = FrameContextConsumer; exports.default = Frame_default; exports.useFrame = useFrame; }); //# sourceMappingURL=react-frame-component.umd.js.map