@willbooster/react-frame-component 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -46,13 +46,13 @@ ReactDOM.render(
46
46
 
47
47
  ###### head
48
48
 
49
- `head: PropTypes.node`
49
+ `head?: React.ReactNode`
50
50
 
51
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
52
 
53
53
  ###### initialContent
54
54
 
55
- `initialContent: PropTypes.string`
55
+ `initialContent?: string`
56
56
 
57
57
  Defaults to `'<!DOCTYPE html><html><head></head><body><div></div></body></html>'`
58
58
 
@@ -60,7 +60,7 @@ The `initialContent` props is the initial html injected into frame. It is only i
60
60
 
61
61
  ###### mountTarget
62
62
 
63
- `mountTarget: PropTypes.string`
63
+ `mountTarget?: string`
64
64
 
65
65
  The `mountTarget` props is a css selector (#target/.target) that specifies where in the `initialContent` of the iframe, children will be mounted.
66
66
 
@@ -73,7 +73,7 @@ The `mountTarget` props is a css selector (#target/.target) that specifies where
73
73
 
74
74
  ###### dangerouslyUseDocWrite
75
75
 
76
- `dangerouslyUseDocWrite: PropTypes.bool`
76
+ `dangerouslyUseDocWrite?: boolean`
77
77
 
78
78
  Defaults to `false`
79
79
 
@@ -81,8 +81,8 @@ The frame's initial content, as defined by the `initialContent` prop, is populat
81
81
 
82
82
  ###### contentDidMount and contentDidUpdate
83
83
 
84
- `contentDidMount: PropTypes.func`
85
- `contentDidUpdate: PropTypes.func`
84
+ `contentDidMount?: () => void`
85
+ `contentDidUpdate?: () => void`
86
86
 
87
87
  `contentDidMount` and `contentDidUpdate` are conceptually equivalent to
88
88
  `componentDidMount` and `componentDidUpdate`, respectively. The reason these are
@@ -93,7 +93,7 @@ when the frame contents are mounted and updated.
93
93
 
94
94
  ###### ref
95
95
 
96
- `ref: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ current: PropTypes.instanceOf(Element) }) ])`
96
+ `ref?: React.Ref<HTMLIFrameElement>`
97
97
 
98
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
99
 
@@ -0,0 +1,2 @@
1
+ "use strict";let e=require("react");var t=class extends e.Component{componentDidMount(){this.props.contentDidMount()}componentDidUpdate(){this.props.contentDidUpdate()}render(){return e.Children.only(this.props.children)}};exports.default=t;
2
+ //# sourceMappingURL=Content.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Content.cjs","names":["Component","Children"],"sources":["../src/Content.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport { Children, Component } from 'react';\n\ninterface ContentProps {\n children: ReactElement;\n contentDidMount: () => void;\n contentDidUpdate: () => void;\n}\n\nexport default class Content extends Component<ContentProps> {\n override componentDidMount(): void {\n this.props.contentDidMount();\n }\n\n override componentDidUpdate(): void {\n this.props.contentDidUpdate();\n }\n\n override render(): ReactElement {\n return Children.only(this.props.children);\n }\n}\n"],"mappings":"oCASA,IAAqB,EAArB,cAAqCA,EAAAA,SAAwB,CAC3D,mBAAmC,CACjC,KAAK,MAAM,gBAAgB,CAC7B,CAEA,oBAAoC,CAClC,KAAK,MAAM,iBAAiB,CAC9B,CAEA,QAAgC,CAC9B,OAAOC,EAAAA,SAAS,KAAK,KAAK,MAAM,QAAQ,CAC1C,CACF"}
@@ -0,0 +1,14 @@
1
+ import type { ReactElement } from 'react';
2
+ import { Component } from 'react';
3
+ interface ContentProps {
4
+ children: ReactElement;
5
+ contentDidMount: () => void;
6
+ contentDidUpdate: () => void;
7
+ }
8
+ export default class Content extends Component<ContentProps> {
9
+ componentDidMount(): void;
10
+ componentDidUpdate(): void;
11
+ render(): ReactElement;
12
+ }
13
+ export {};
14
+ //# sourceMappingURL=Content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Content.d.ts","sourceRoot":"","sources":["../src/Content.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAY,SAAS,EAAE,MAAM,OAAO,CAAC;AAE5C,UAAU,YAAY;IACpB,QAAQ,EAAE,YAAY,CAAC;IACvB,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,gBAAgB,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,SAAS,CAAC,YAAY,CAAC;IACjD,iBAAiB,IAAI,IAAI,CAEjC;IAEQ,kBAAkB,IAAI,IAAI,CAElC;IAEQ,MAAM,IAAI,YAAY,CAE9B;CACF"}
@@ -0,0 +1,2 @@
1
+ import{Children as e,Component as t}from"react";var n=class extends t{componentDidMount(){this.props.contentDidMount()}componentDidUpdate(){this.props.contentDidUpdate()}render(){return e.only(this.props.children)}};export{n as default};
2
+ //# sourceMappingURL=Content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Content.js","names":[],"sources":["../src/Content.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport { Children, Component } from 'react';\n\ninterface ContentProps {\n children: ReactElement;\n contentDidMount: () => void;\n contentDidUpdate: () => void;\n}\n\nexport default class Content extends Component<ContentProps> {\n override componentDidMount(): void {\n this.props.contentDidMount();\n }\n\n override componentDidUpdate(): void {\n this.props.contentDidUpdate();\n }\n\n override render(): ReactElement {\n return Children.only(this.props.children);\n }\n}\n"],"mappings":"gDASA,IAAqB,EAArB,cAAqC,CAAwB,CAC3D,mBAAmC,CACjC,KAAK,MAAM,gBAAgB,CAC7B,CAEA,oBAAoC,CAClC,KAAK,MAAM,iBAAiB,CAC9B,CAEA,QAAgC,CAC9B,OAAO,EAAS,KAAK,KAAK,MAAM,QAAQ,CAC1C,CACF"}
@@ -0,0 +1,2 @@
1
+ "use strict";const e=require("./_virtual/_rolldown/runtime.cjs");let t=require("react");t=e.__toESM(t,1);let n,r;typeof document<`u`&&(n=document),globalThis.window!==void 0&&(r=globalThis.window);const i=t.createContext({document:n,window:r}),a=()=>t.useContext(i),{Provider:o,Consumer:s}=i;exports.FrameContext=i,exports.FrameContextConsumer=s,exports.FrameContextProvider=o,exports.useFrame=a;
2
+ //# sourceMappingURL=Context.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Context.cjs","names":["React"],"sources":["../src/Context.ts"],"sourcesContent":["import * as React from 'react';\n\nexport interface FrameContextProps {\n document?: Document;\n window?: Window;\n}\n\nlet doc: Document | undefined;\nlet win: Window | undefined;\nif (typeof document !== 'undefined') {\n doc = document;\n}\nif (globalThis.window !== undefined) {\n win = globalThis.window;\n}\n\nexport const FrameContext = React.createContext<FrameContextProps>({ document: doc, window: win });\n\nexport const useFrame = (): FrameContextProps => React.useContext(FrameContext);\n\nexport const { Provider: FrameContextProvider, Consumer: FrameContextConsumer } = FrameContext;\n"],"mappings":"yGAOA,IAAI,EACA,EACA,OAAO,SAAa,MACtB,EAAM,UAEJ,WAAW,SAAW,IAAA,KACxB,EAAM,WAAW,QAGnB,MAAa,EAAeA,EAAM,cAAiC,CAAE,SAAU,EAAK,OAAQ,CAAI,CAAC,EAEpF,MAAoCA,EAAM,WAAW,CAAY,EAEjE,CAAE,SAAU,EAAsB,SAAU,GAAyB"}
@@ -0,0 +1,9 @@
1
+ import * as React from 'react';
2
+ export interface FrameContextProps {
3
+ document?: Document;
4
+ window?: Window;
5
+ }
6
+ export declare const FrameContext: React.Context<FrameContextProps>;
7
+ export declare const useFrame: () => FrameContextProps;
8
+ export declare const FrameContextProvider: React.Provider<FrameContextProps>, FrameContextConsumer: React.Consumer<FrameContextProps>;
9
+ //# sourceMappingURL=Context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Context.d.ts","sourceRoot":"","sources":["../src/Context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAWD,eAAO,MAAM,YAAY,kCAAyE,CAAC;AAEnG,eAAO,MAAM,QAAQ,QAAO,iBAAmD,CAAC;AAEhF,eAAO,MAAkB,oBAAoB,qCAAY,oBAAoB,mCAAiB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import*as e from"react";let t,n;typeof document<`u`&&(t=document),globalThis.window!==void 0&&(n=globalThis.window);const r=e.createContext({document:t,window:n}),i=()=>e.useContext(r),{Provider:a,Consumer:o}=r;export{r as FrameContext,o as FrameContextConsumer,a as FrameContextProvider,i as useFrame};
2
+ //# sourceMappingURL=Context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Context.js","names":[],"sources":["../src/Context.ts"],"sourcesContent":["import * as React from 'react';\n\nexport interface FrameContextProps {\n document?: Document;\n window?: Window;\n}\n\nlet doc: Document | undefined;\nlet win: Window | undefined;\nif (typeof document !== 'undefined') {\n doc = document;\n}\nif (globalThis.window !== undefined) {\n win = globalThis.window;\n}\n\nexport const FrameContext = React.createContext<FrameContextProps>({ document: doc, window: win });\n\nexport const useFrame = (): FrameContextProps => React.useContext(FrameContext);\n\nexport const { Provider: FrameContextProvider, Consumer: FrameContextConsumer } = FrameContext;\n"],"mappings":"wBAOA,IAAI,EACA,EACA,OAAO,SAAa,MACtB,EAAM,UAEJ,WAAW,SAAW,IAAA,KACxB,EAAM,WAAW,QAGnB,MAAa,EAAe,EAAM,cAAiC,CAAE,SAAU,EAAK,OAAQ,CAAI,CAAC,EAEpF,MAAoC,EAAM,WAAW,CAAY,EAEjE,CAAE,SAAU,EAAsB,SAAU,GAAyB"}
package/dist/Frame.cjs ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";const e=require("./_virtual/_rolldown/runtime.cjs"),t=require("./Context.cjs"),n=require("./Content.cjs");let r=require("react");r=e.__toESM(r,1);let i=require("react-dom");i=e.__toESM(i,1);let a=require("react/jsx-runtime");const o=`<!DOCTYPE html><html><head></head><body><div class="frame-root"></div></body></html>`;var s=class extends r.Component{constructor(...e){super(...e),this._isMounted=!1,this.nodeRef=r.createRef(),this.state={iframeLoaded:!1},this.setRef=e=>{this.nodeRef.current=e;let{forwardedRef:t}=this.props;typeof t==`function`?t(e):t&&(t.current=e)},this.handleLoad=()=>{this.state.iframeLoaded||this.setState({iframeLoaded:!0})}}componentDidMount(){this._isMounted=!0,this.getDoc()&&this.nodeRef.current?.contentWindow?.addEventListener(`DOMContentLoaded`,this.handleLoad),this.props.dangerouslyUseDocWrite&&this.handleLoad()}componentWillUnmount(){this._isMounted=!1,this.nodeRef.current?.contentWindow?.removeEventListener(`DOMContentLoaded`,this.handleLoad)}getDoc(){return this.nodeRef.current?.contentDocument??void 0}getMountTarget(){let e=this.getDoc();if(!(!e||!e.body))return this.props.mountTarget?e.querySelector(this.props.mountTarget)??void 0:e.body.children[0]}renderFrameContents(){if(!this._isMounted)return;let e=this.getDoc();if(!e)return;let{contentDidMount:r=()=>{},contentDidUpdate:s=()=>{}}=this.props,c=e.defaultView??void 0;(!this._contextValue||this._contextValue.document!==e||this._contextValue.window!==c)&&(this._contextValue={document:e,window:c});let l=(0,a.jsx)(n.default,{contentDidMount:r,contentDidUpdate:s,children:(0,a.jsx)(t.FrameContextProvider,{value:this._contextValue,children:(0,a.jsx)(`div`,{className:`frame-content`,children:this.props.children})})});this.props.dangerouslyUseDocWrite&&e.body.children.length===0&&(e.open(`text/html`,`replace`),e.write(this.props.initialContent??o),e.close());let u=this.getMountTarget();if(u)return[i.createPortal(this.props.head,e.head,`head`),i.createPortal(l,u,`contents`)]}render(){let{children:e,contentDidMount:t,contentDidUpdate:n,dangerouslyUseDocWrite:r,forwardedRef:i,head:s,initialContent:c,mountTarget:l,...u}=this.props;return r||(u.srcDoc=c??o),(0,a.jsx)(`iframe`,{...u,ref:this.setRef,onLoad:this.handleLoad,children:this.state.iframeLoaded&&this.renderFrameContents()})}},c=r.forwardRef((e,t)=>(0,a.jsx)(s,{...e,forwardedRef:t}));exports.default=c;
2
+ //# sourceMappingURL=Frame.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Frame.cjs","names":["React","Content","FrameContextProvider","ReactDOM"],"sources":["../src/Frame.tsx"],"sourcesContent":["import * as React from 'react';\nimport * as ReactDOM from 'react-dom';\nimport type { FrameContextProps } from './Context.js';\nimport { FrameContextProvider } from './Context.js';\nimport Content from './Content.js';\n\ninterface FrameOwnProps extends React.IframeHTMLAttributes<HTMLIFrameElement> {\n head?: React.ReactNode | undefined;\n mountTarget?: string | undefined;\n initialContent?: string | undefined;\n contentDidMount?: (() => void) | undefined;\n contentDidUpdate?: (() => void) | undefined;\n dangerouslyUseDocWrite?: boolean | undefined;\n children?: React.ReactNode | undefined;\n}\n\n// The public props type accepts `ref` (forwarded to the underlying iframe element),\n// while the internal class must not declare `ref` in its props so that a ref on\n// `Frame` itself keeps referring to the component instance.\nexport type FrameComponentProps = FrameOwnProps & React.RefAttributes<HTMLIFrameElement>;\n\ninterface InternalFrameProps extends FrameOwnProps {\n forwardedRef?: React.ForwardedRef<HTMLIFrameElement> | undefined;\n}\n\ninterface FrameState {\n iframeLoaded: boolean;\n}\n\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.\nconst DEFAULT_INITIAL_CONTENT = '<!DOCTYPE html><html><head></head><body><div class=\"frame-root\"></div></body></html>';\n\nexport class Frame extends React.Component<InternalFrameProps, FrameState> {\n private _isMounted = false;\n private _contextValue: FrameContextProps | undefined;\n private readonly nodeRef: React.MutableRefObject<HTMLIFrameElement | null> = React.createRef();\n\n override state: FrameState = { iframeLoaded: false };\n\n override componentDidMount(): void {\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 override componentWillUnmount(): void {\n this._isMounted = false;\n\n // The listener was added to the iframe's content window in componentDidMount.\n this.nodeRef.current?.contentWindow?.removeEventListener('DOMContentLoaded', this.handleLoad);\n }\n\n getDoc(): Document | undefined {\n return this.nodeRef.current?.contentDocument ?? undefined;\n }\n\n getMountTarget(): Element | undefined {\n const doc = this.getDoc();\n\n if (!doc || !doc.body) {\n return undefined;\n }\n\n if (this.props.mountTarget) {\n return doc.querySelector(this.props.mountTarget) ?? undefined;\n }\n\n return doc.body.children[0];\n }\n\n setRef = (node: HTMLIFrameElement | null): void => {\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 = (): void => {\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 renderFrameContents(): React.ReactNode {\n if (!this._isMounted) {\n return undefined;\n }\n\n const doc = this.getDoc();\n\n if (!doc) {\n return undefined;\n }\n\n const { contentDidMount = () => {}, contentDidUpdate = () => {} } = this.props;\n\n const win = doc.defaultView ?? undefined;\n // Reuse the context value across renders so consumers only re-render when the\n // document or window actually changes, not on every render of Frame.\n if (!this._contextValue || this._contextValue.document !== doc || this._contextValue.window !== win) {\n this._contextValue = { document: doc, window: win };\n }\n const contents = (\n <Content contentDidMount={contentDidMount} contentDidUpdate={contentDidUpdate}>\n <FrameContextProvider value={this._contextValue}>\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 ?? DEFAULT_INITIAL_CONTENT);\n doc.close();\n }\n\n const mountTarget = this.getMountTarget();\n\n if (!mountTarget) {\n return undefined;\n }\n\n return [\n ReactDOM.createPortal(this.props.head, doc.head, 'head'),\n ReactDOM.createPortal(contents, mountTarget, 'contents'),\n ];\n }\n\n override render(): React.ReactElement {\n // The iframe isn't ready so we drop children from the iframe props here. #12, #17\n const {\n children: _children,\n contentDidMount: _contentDidMount,\n contentDidUpdate: _contentDidUpdate,\n dangerouslyUseDocWrite,\n forwardedRef: _forwardedRef,\n head: _head,\n initialContent,\n mountTarget: _mountTarget,\n ...iframeProps\n } = this.props;\n\n if (!dangerouslyUseDocWrite) {\n iframeProps.srcDoc = initialContent ?? DEFAULT_INITIAL_CONTENT;\n }\n\n return (\n // oxlint-disable-next-line jsx-a11y/iframe-has-title -- consumers can pass `title` via the props spread\n <iframe {...iframeProps} ref={this.setRef} onLoad={this.handleLoad}>\n {this.state.iframeLoaded && this.renderFrameContents()}\n </iframe>\n );\n }\n}\n\nexport default React.forwardRef<HTMLIFrameElement, FrameOwnProps>((props, ref) => (\n <Frame {...props} forwardedRef={ref} />\n));\n"],"mappings":"8OAiCA,MAAM,EAA0B,uFAEhC,IAAa,EAAb,cAA2BA,EAAM,SAA0C,+CACpD,gBAEwDA,EAAM,UAAU,aAEhE,CAAE,aAAc,EAAM,cAyCzC,GAAyC,CACjD,KAAK,QAAQ,QAAU,EAEvB,GAAM,CAAE,gBAAiB,KAAK,MAC1B,OAAO,GAAiB,WAC1B,EAAa,CAAI,EACR,IACT,EAAa,QAAU,EAE3B,sBAEyB,CAElB,KAAK,MAAM,cACd,KAAK,SAAS,CAAE,aAAc,EAAK,CAAC,CAExC,EAvDA,mBAAmC,CACjC,KAAK,WAAa,GAEN,KAAK,OAEX,GACJ,KAAK,QAAQ,SAAS,eAAe,iBAAiB,mBAAoB,KAAK,UAAU,EAGvF,KAAK,MAAM,wBACb,KAAK,WAAW,CAEpB,CAEA,sBAAsC,CACpC,KAAK,WAAa,GAGlB,KAAK,QAAQ,SAAS,eAAe,oBAAoB,mBAAoB,KAAK,UAAU,CAC9F,CAEA,QAA+B,CAC7B,OAAO,KAAK,QAAQ,SAAS,iBAAmB,IAAA,EAClD,CAEA,gBAAsC,CACpC,IAAM,EAAM,KAAK,OAAO,EAEpB,MAAC,GAAO,CAAC,EAAI,MAQjB,OAJI,KAAK,MAAM,YACN,EAAI,cAAc,KAAK,MAAM,WAAW,GAAK,IAAA,GAG/C,EAAI,KAAK,SAAS,EAC3B,CAoBA,qBAAuC,CACrC,GAAI,CAAC,KAAK,WACR,OAGF,IAAM,EAAM,KAAK,OAAO,EAExB,GAAI,CAAC,EACH,OAGF,GAAM,CAAE,sBAAwB,CAAC,EAAG,uBAAyB,CAAC,GAAM,KAAK,MAEnE,EAAM,EAAI,aAAe,IAAA,IAG3B,CAAC,KAAK,eAAiB,KAAK,cAAc,WAAa,GAAO,KAAK,cAAc,SAAW,KAC9F,KAAK,cAAgB,CAAE,SAAU,EAAK,OAAQ,CAAI,GAEpD,IAAM,GACJ,EAAA,EAAA,IAAA,CAACC,EAAAA,QAAD,CAA0B,kBAAmC,6BAC3D,EAAA,EAAA,IAAA,CAACC,EAAAA,qBAAD,CAAsB,MAAO,KAAK,wBAChC,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,yBAAiB,KAAK,MAAM,QAAc,CAAA,CACrC,CAAA,CACf,CAAA,EAGP,KAAK,MAAM,wBAA0B,EAAI,KAAK,SAAS,SAAW,IACpE,EAAI,KAAK,YAAa,SAAS,EAC/B,EAAI,MAAM,KAAK,MAAM,gBAAkB,CAAuB,EAC9D,EAAI,MAAM,GAGZ,IAAM,EAAc,KAAK,eAAe,EAEnC,KAIL,MAAO,CACLC,EAAS,aAAa,KAAK,MAAM,KAAM,EAAI,KAAM,MAAM,EACvDA,EAAS,aAAa,EAAU,EAAa,UAAU,CACzD,CACF,CAEA,QAAsC,CAEpC,GAAM,CACJ,SAAU,EACV,gBAAiB,EACjB,iBAAkB,EAClB,yBACA,aAAc,EACd,KAAM,EACN,iBACA,YAAa,EACb,GAAG,GACD,KAAK,MAMT,OAJK,IACH,EAAY,OAAS,GAAkB,IAKvC,EAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,GAAI,EAAa,IAAK,KAAK,OAAQ,OAAQ,KAAK,oBACrD,KAAK,MAAM,cAAgB,KAAK,oBAAoB,CAC/C,CAAA,CAEZ,CACF,EAEA,EAAeH,EAAM,YAA8C,EAAO,KACxE,EAAA,EAAA,IAAA,CAAC,EAAD,CAAO,GAAI,EAAO,aAAc,CAAM,CAAA,CACvC"}
@@ -0,0 +1,34 @@
1
+ import * as React from 'react';
2
+ interface FrameOwnProps extends React.IframeHTMLAttributes<HTMLIFrameElement> {
3
+ head?: React.ReactNode | undefined;
4
+ mountTarget?: string | undefined;
5
+ initialContent?: string | undefined;
6
+ contentDidMount?: (() => void) | undefined;
7
+ contentDidUpdate?: (() => void) | undefined;
8
+ dangerouslyUseDocWrite?: boolean | undefined;
9
+ children?: React.ReactNode | undefined;
10
+ }
11
+ export type FrameComponentProps = FrameOwnProps & React.RefAttributes<HTMLIFrameElement>;
12
+ interface InternalFrameProps extends FrameOwnProps {
13
+ forwardedRef?: React.ForwardedRef<HTMLIFrameElement> | undefined;
14
+ }
15
+ interface FrameState {
16
+ iframeLoaded: boolean;
17
+ }
18
+ export declare class Frame extends React.Component<InternalFrameProps, FrameState> {
19
+ private _isMounted;
20
+ private _contextValue;
21
+ private readonly nodeRef;
22
+ state: FrameState;
23
+ componentDidMount(): void;
24
+ componentWillUnmount(): void;
25
+ getDoc(): Document | undefined;
26
+ getMountTarget(): Element | undefined;
27
+ setRef: (node: HTMLIFrameElement | null) => void;
28
+ handleLoad: () => void;
29
+ renderFrameContents(): React.ReactNode;
30
+ render(): React.ReactElement;
31
+ }
32
+ declare const _default: React.ForwardRefExoticComponent<FrameOwnProps & React.RefAttributes<HTMLIFrameElement>>;
33
+ export default _default;
34
+ //# sourceMappingURL=Frame.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Frame.d.ts","sourceRoot":"","sources":["../src/Frame.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,UAAU,aAAc,SAAQ,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC;IAC3E,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,eAAe,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IAC3C,gBAAgB,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IAC5C,sBAAsB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC;CACxC;AAKD,MAAM,MAAM,mBAAmB,GAAG,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC;AAEzF,UAAU,kBAAmB,SAAQ,aAAa;IAChD,YAAY,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,iBAAiB,CAAC,GAAG,SAAS,CAAC;CAClE;AAED,UAAU,UAAU;IAClB,YAAY,EAAE,OAAO,CAAC;CACvB;AAQD,qBAAa,KAAM,SAAQ,KAAK,CAAC,SAAS,CAAC,kBAAkB,EAAE,UAAU,CAAC;IACxE,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuE;IAEtF,KAAK,EAAE,UAAU,CAA2B;IAE5C,iBAAiB,IAAI,IAAI,CAYjC;IAEQ,oBAAoB,IAAI,IAAI,CAKpC;IAED,MAAM,IAAI,QAAQ,GAAG,SAAS,CAE7B;IAED,cAAc,IAAI,OAAO,GAAG,SAAS,CAYpC;IAED,MAAM,SAAU,iBAAiB,GAAG,IAAI,KAAG,IAAI,CAS7C;IAEF,UAAU,QAAO,IAAI,CAKnB;IAEF,mBAAmB,IAAI,KAAK,CAAC,SAAS,CA2CrC;IAEQ,MAAM,IAAI,KAAK,CAAC,YAAY,CAwBpC;CACF"}
package/dist/Frame.js ADDED
@@ -0,0 +1,2 @@
1
+ import{FrameContextProvider as e}from"./Context.js";import t from"./Content.js";import*as n from"react";import*as r from"react-dom";import{jsx as i}from"react/jsx-runtime";const a=`<!DOCTYPE html><html><head></head><body><div class="frame-root"></div></body></html>`;var o=class extends n.Component{constructor(...e){super(...e),this._isMounted=!1,this.nodeRef=n.createRef(),this.state={iframeLoaded:!1},this.setRef=e=>{this.nodeRef.current=e;let{forwardedRef:t}=this.props;typeof t==`function`?t(e):t&&(t.current=e)},this.handleLoad=()=>{this.state.iframeLoaded||this.setState({iframeLoaded:!0})}}componentDidMount(){this._isMounted=!0,this.getDoc()&&this.nodeRef.current?.contentWindow?.addEventListener(`DOMContentLoaded`,this.handleLoad),this.props.dangerouslyUseDocWrite&&this.handleLoad()}componentWillUnmount(){this._isMounted=!1,this.nodeRef.current?.contentWindow?.removeEventListener(`DOMContentLoaded`,this.handleLoad)}getDoc(){return this.nodeRef.current?.contentDocument??void 0}getMountTarget(){let e=this.getDoc();if(!(!e||!e.body))return this.props.mountTarget?e.querySelector(this.props.mountTarget)??void 0:e.body.children[0]}renderFrameContents(){if(!this._isMounted)return;let n=this.getDoc();if(!n)return;let{contentDidMount:o=()=>{},contentDidUpdate:s=()=>{}}=this.props,c=n.defaultView??void 0;(!this._contextValue||this._contextValue.document!==n||this._contextValue.window!==c)&&(this._contextValue={document:n,window:c});let l=i(t,{contentDidMount:o,contentDidUpdate:s,children:i(e,{value:this._contextValue,children:i(`div`,{className:`frame-content`,children:this.props.children})})});this.props.dangerouslyUseDocWrite&&n.body.children.length===0&&(n.open(`text/html`,`replace`),n.write(this.props.initialContent??a),n.close());let u=this.getMountTarget();if(u)return[r.createPortal(this.props.head,n.head,`head`),r.createPortal(l,u,`contents`)]}render(){let{children:e,contentDidMount:t,contentDidUpdate:n,dangerouslyUseDocWrite:r,forwardedRef:o,head:s,initialContent:c,mountTarget:l,...u}=this.props;return r||(u.srcDoc=c??a),i(`iframe`,{...u,ref:this.setRef,onLoad:this.handleLoad,children:this.state.iframeLoaded&&this.renderFrameContents()})}},s=n.forwardRef((e,t)=>i(o,{...e,forwardedRef:t}));export{s as default};
2
+ //# sourceMappingURL=Frame.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Frame.js","names":[],"sources":["../src/Frame.tsx"],"sourcesContent":["import * as React from 'react';\nimport * as ReactDOM from 'react-dom';\nimport type { FrameContextProps } from './Context.js';\nimport { FrameContextProvider } from './Context.js';\nimport Content from './Content.js';\n\ninterface FrameOwnProps extends React.IframeHTMLAttributes<HTMLIFrameElement> {\n head?: React.ReactNode | undefined;\n mountTarget?: string | undefined;\n initialContent?: string | undefined;\n contentDidMount?: (() => void) | undefined;\n contentDidUpdate?: (() => void) | undefined;\n dangerouslyUseDocWrite?: boolean | undefined;\n children?: React.ReactNode | undefined;\n}\n\n// The public props type accepts `ref` (forwarded to the underlying iframe element),\n// while the internal class must not declare `ref` in its props so that a ref on\n// `Frame` itself keeps referring to the component instance.\nexport type FrameComponentProps = FrameOwnProps & React.RefAttributes<HTMLIFrameElement>;\n\ninterface InternalFrameProps extends FrameOwnProps {\n forwardedRef?: React.ForwardedRef<HTMLIFrameElement> | undefined;\n}\n\ninterface FrameState {\n iframeLoaded: boolean;\n}\n\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.\nconst DEFAULT_INITIAL_CONTENT = '<!DOCTYPE html><html><head></head><body><div class=\"frame-root\"></div></body></html>';\n\nexport class Frame extends React.Component<InternalFrameProps, FrameState> {\n private _isMounted = false;\n private _contextValue: FrameContextProps | undefined;\n private readonly nodeRef: React.MutableRefObject<HTMLIFrameElement | null> = React.createRef();\n\n override state: FrameState = { iframeLoaded: false };\n\n override componentDidMount(): void {\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 override componentWillUnmount(): void {\n this._isMounted = false;\n\n // The listener was added to the iframe's content window in componentDidMount.\n this.nodeRef.current?.contentWindow?.removeEventListener('DOMContentLoaded', this.handleLoad);\n }\n\n getDoc(): Document | undefined {\n return this.nodeRef.current?.contentDocument ?? undefined;\n }\n\n getMountTarget(): Element | undefined {\n const doc = this.getDoc();\n\n if (!doc || !doc.body) {\n return undefined;\n }\n\n if (this.props.mountTarget) {\n return doc.querySelector(this.props.mountTarget) ?? undefined;\n }\n\n return doc.body.children[0];\n }\n\n setRef = (node: HTMLIFrameElement | null): void => {\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 = (): void => {\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 renderFrameContents(): React.ReactNode {\n if (!this._isMounted) {\n return undefined;\n }\n\n const doc = this.getDoc();\n\n if (!doc) {\n return undefined;\n }\n\n const { contentDidMount = () => {}, contentDidUpdate = () => {} } = this.props;\n\n const win = doc.defaultView ?? undefined;\n // Reuse the context value across renders so consumers only re-render when the\n // document or window actually changes, not on every render of Frame.\n if (!this._contextValue || this._contextValue.document !== doc || this._contextValue.window !== win) {\n this._contextValue = { document: doc, window: win };\n }\n const contents = (\n <Content contentDidMount={contentDidMount} contentDidUpdate={contentDidUpdate}>\n <FrameContextProvider value={this._contextValue}>\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 ?? DEFAULT_INITIAL_CONTENT);\n doc.close();\n }\n\n const mountTarget = this.getMountTarget();\n\n if (!mountTarget) {\n return undefined;\n }\n\n return [\n ReactDOM.createPortal(this.props.head, doc.head, 'head'),\n ReactDOM.createPortal(contents, mountTarget, 'contents'),\n ];\n }\n\n override render(): React.ReactElement {\n // The iframe isn't ready so we drop children from the iframe props here. #12, #17\n const {\n children: _children,\n contentDidMount: _contentDidMount,\n contentDidUpdate: _contentDidUpdate,\n dangerouslyUseDocWrite,\n forwardedRef: _forwardedRef,\n head: _head,\n initialContent,\n mountTarget: _mountTarget,\n ...iframeProps\n } = this.props;\n\n if (!dangerouslyUseDocWrite) {\n iframeProps.srcDoc = initialContent ?? DEFAULT_INITIAL_CONTENT;\n }\n\n return (\n // oxlint-disable-next-line jsx-a11y/iframe-has-title -- consumers can pass `title` via the props spread\n <iframe {...iframeProps} ref={this.setRef} onLoad={this.handleLoad}>\n {this.state.iframeLoaded && this.renderFrameContents()}\n </iframe>\n );\n }\n}\n\nexport default React.forwardRef<HTMLIFrameElement, FrameOwnProps>((props, ref) => (\n <Frame {...props} forwardedRef={ref} />\n));\n"],"mappings":"4KAiCA,MAAM,EAA0B,uFAEhC,IAAa,EAAb,cAA2B,EAAM,SAA0C,+CACpD,gBAEwD,EAAM,UAAU,aAEhE,CAAE,aAAc,EAAM,cAyCzC,GAAyC,CACjD,KAAK,QAAQ,QAAU,EAEvB,GAAM,CAAE,gBAAiB,KAAK,MAC1B,OAAO,GAAiB,WAC1B,EAAa,CAAI,EACR,IACT,EAAa,QAAU,EAE3B,sBAEyB,CAElB,KAAK,MAAM,cACd,KAAK,SAAS,CAAE,aAAc,EAAK,CAAC,CAExC,EAvDA,mBAAmC,CACjC,KAAK,WAAa,GAEN,KAAK,OAEX,GACJ,KAAK,QAAQ,SAAS,eAAe,iBAAiB,mBAAoB,KAAK,UAAU,EAGvF,KAAK,MAAM,wBACb,KAAK,WAAW,CAEpB,CAEA,sBAAsC,CACpC,KAAK,WAAa,GAGlB,KAAK,QAAQ,SAAS,eAAe,oBAAoB,mBAAoB,KAAK,UAAU,CAC9F,CAEA,QAA+B,CAC7B,OAAO,KAAK,QAAQ,SAAS,iBAAmB,IAAA,EAClD,CAEA,gBAAsC,CACpC,IAAM,EAAM,KAAK,OAAO,EAEpB,MAAC,GAAO,CAAC,EAAI,MAQjB,OAJI,KAAK,MAAM,YACN,EAAI,cAAc,KAAK,MAAM,WAAW,GAAK,IAAA,GAG/C,EAAI,KAAK,SAAS,EAC3B,CAoBA,qBAAuC,CACrC,GAAI,CAAC,KAAK,WACR,OAGF,IAAM,EAAM,KAAK,OAAO,EAExB,GAAI,CAAC,EACH,OAGF,GAAM,CAAE,sBAAwB,CAAC,EAAG,uBAAyB,CAAC,GAAM,KAAK,MAEnE,EAAM,EAAI,aAAe,IAAA,IAG3B,CAAC,KAAK,eAAiB,KAAK,cAAc,WAAa,GAAO,KAAK,cAAc,SAAW,KAC9F,KAAK,cAAgB,CAAE,SAAU,EAAK,OAAQ,CAAI,GAEpD,IAAM,EACJ,EAAC,EAAD,CAA0B,kBAAmC,4BAC3D,EAAC,EAAD,CAAsB,MAAO,KAAK,uBAChC,EAAC,MAAD,CAAK,UAAU,yBAAiB,KAAK,MAAM,QAAc,CAAA,CACrC,CAAA,CACf,CAAA,EAGP,KAAK,MAAM,wBAA0B,EAAI,KAAK,SAAS,SAAW,IACpE,EAAI,KAAK,YAAa,SAAS,EAC/B,EAAI,MAAM,KAAK,MAAM,gBAAkB,CAAuB,EAC9D,EAAI,MAAM,GAGZ,IAAM,EAAc,KAAK,eAAe,EAEnC,KAIL,MAAO,CACL,EAAS,aAAa,KAAK,MAAM,KAAM,EAAI,KAAM,MAAM,EACvD,EAAS,aAAa,EAAU,EAAa,UAAU,CACzD,CACF,CAEA,QAAsC,CAEpC,GAAM,CACJ,SAAU,EACV,gBAAiB,EACjB,iBAAkB,EAClB,yBACA,aAAc,EACd,KAAM,EACN,iBACA,YAAa,EACb,GAAG,GACD,KAAK,MAMT,OAJK,IACH,EAAY,OAAS,GAAkB,GAKvC,EAAC,SAAD,CAAQ,GAAI,EAAa,IAAK,KAAK,OAAQ,OAAQ,KAAK,oBACrD,KAAK,MAAM,cAAgB,KAAK,oBAAoB,CAC/C,CAAA,CAEZ,CACF,EAEA,EAAe,EAAM,YAA8C,EAAO,IACxE,EAAC,EAAD,CAAO,GAAI,EAAO,aAAc,CAAM,CAAA,CACvC"}
@@ -0,0 +1 @@
1
+ "use strict";var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));exports.__toESM=s;
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("./Context.cjs"),t=require("./Frame.cjs");exports.FrameContext=e.FrameContext,exports.FrameContextConsumer=e.FrameContextConsumer,exports.FrameContextProvider=e.FrameContextProvider,exports.default=t.default,exports.useFrame=e.useFrame;
@@ -0,0 +1,5 @@
1
+ export { default } from './Frame.js';
2
+ export type { FrameComponentProps } from './Frame.js';
3
+ export { FrameContext, FrameContextConsumer, FrameContextProvider, useFrame } from './Context.js';
4
+ export type { FrameContextProps } from './Context.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,YAAY,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAClG,YAAY,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ import{FrameContext as e,FrameContextConsumer as t,FrameContextProvider as n,useFrame as r}from"./Context.js";import i from"./Frame.js";export{e as FrameContext,t as FrameContextConsumer,n as FrameContextProvider,i as default,r as useFrame};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@willbooster/react-frame-component",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "React component to wrap your application or component in an iFrame for encapsulation purposes",
5
5
  "keywords": [
6
6
  "React",
@@ -24,21 +24,20 @@
24
24
  "type": "module",
25
25
  "exports": {
26
26
  ".": {
27
- "types": "./index.d.ts",
28
- "import": "./dist/react-frame-component.esm.js",
29
- "require": "./dist/react-frame-component.umd.js"
27
+ "types": "./dist/index.d.ts",
28
+ "import": "./dist/index.js",
29
+ "require": "./dist/index.cjs"
30
30
  }
31
31
  },
32
- "main": "dist/react-frame-component.umd.js",
33
- "module": "dist/react-frame-component.esm.js",
34
- "types": "index.d.ts",
32
+ "main": "dist/index.cjs",
33
+ "module": "dist/index.js",
34
+ "types": "dist/index.d.ts",
35
35
  "files": [
36
- "dist",
37
- "index.d.ts"
36
+ "dist/"
38
37
  ],
39
38
  "scripts": {
40
- "build": "vite build",
41
- "build:example": "vite build --config vite.example.config.js",
39
+ "build": "build-ts lib",
40
+ "build:example": "vite build --config vite.example.config.ts",
42
41
  "clean": "rimraf dist",
43
42
  "cleanup": "yarn format && yarn lint-fix",
44
43
  "format": "sort-package-json && yarn format-code",
@@ -51,6 +50,7 @@
51
50
  "test": "vitest run",
52
51
  "test:watch": "vitest",
53
52
  "test/ci-setup": "playwright install --with-deps chromium firefox",
53
+ "typecheck": "wb typecheck",
54
54
  "verify": "wb verify",
55
55
  "verify-full": "wb verify --full"
56
56
  },
@@ -60,13 +60,16 @@
60
60
  "@testing-library/react": "^16.3.2",
61
61
  "@tsconfig/node-lts": "24.0.0",
62
62
  "@tsconfig/node-ts": "23.6.4",
63
+ "@types/node": "26.1.0",
63
64
  "@types/react": "^18",
65
+ "@types/react-dom": "^18",
64
66
  "@vitejs/plugin-react": "^5.1.4",
65
67
  "@vitest/browser": "^4.0.18",
66
68
  "@vitest/browser-playwright": "^4.0.18",
67
69
  "@willbooster/oxfmt-config": "1.2.2",
68
70
  "@willbooster/oxlint-config": "1.4.8",
69
71
  "@willbooster/wb": "13.22.19",
72
+ "build-ts": "17.1.31",
70
73
  "conventional-changelog-conventionalcommits": "^9.3.1",
71
74
  "lefthook": "2.1.9",
72
75
  "oxfmt": "0.57.0",
@@ -78,11 +81,11 @@
78
81
  "rimraf": "^5.0.5",
79
82
  "semantic-release": "^25.0.3",
80
83
  "sort-package-json": "4.0.0",
84
+ "typescript": "6.0.3",
81
85
  "vite": "8.1.0",
82
86
  "vitest": "^4.0.18"
83
87
  },
84
88
  "peerDependencies": {
85
- "prop-types": "^15.8.1 || ^16.0.0 || ^17.0.0 || ^18.0.0",
86
89
  "react": ">= 16.8 || ^17.0.0 || ^18.0.0 || ^19.0.0",
87
90
  "react-dom": ">= 16.8 || ^17.0.0 || ^18.0.0 || ^19.0.0"
88
91
  },
@@ -1,138 +0,0 @@
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?.contentWindow?.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
- if (!this.state.iframeLoaded) this.setState({ iframeLoaded: true });
89
- };
90
- renderFrameContents() {
91
- if (!this._isMounted) return;
92
- const doc = this.getDoc();
93
- if (!doc) return;
94
- const { contentDidMount, contentDidUpdate } = this.props;
95
- const win = doc.defaultView || doc.parentView;
96
- if (!this._contextValue || this._contextValue.document !== doc || this._contextValue.window !== win) this._contextValue = {
97
- document: doc,
98
- window: win
99
- };
100
- const contents = /* @__PURE__ */ jsx(Content, {
101
- contentDidMount,
102
- contentDidUpdate,
103
- children: /* @__PURE__ */ jsx(FrameContextProvider, {
104
- value: this._contextValue,
105
- children: /* @__PURE__ */ jsx("div", {
106
- className: "frame-content",
107
- children: this.props.children
108
- })
109
- })
110
- });
111
- if (this.props.dangerouslyUseDocWrite && doc.body.children.length === 0) {
112
- doc.open("text/html", "replace");
113
- doc.write(this.props.initialContent);
114
- doc.close();
115
- }
116
- const mountTarget = this.getMountTarget();
117
- if (!mountTarget) return;
118
- return [ReactDOM.createPortal(this.props.head, doc.head, "head"), ReactDOM.createPortal(contents, mountTarget, "contents")];
119
- }
120
- render() {
121
- const { children: _children, contentDidMount: _contentDidMount, contentDidUpdate: _contentDidUpdate, dangerouslyUseDocWrite, forwardedRef: _forwardedRef, head: _head, initialContent, mountTarget: _mountTarget, ...iframeProps } = this.props;
122
- if (!dangerouslyUseDocWrite) iframeProps.srcDoc = initialContent;
123
- return /* @__PURE__ */ jsx("iframe", {
124
- ...iframeProps,
125
- ref: this.setRef,
126
- onLoad: this.handleLoad,
127
- children: this.state.iframeLoaded && this.renderFrameContents()
128
- });
129
- }
130
- };
131
- var Frame_default = React.forwardRef((props, ref) => /* @__PURE__ */ jsx(Frame, {
132
- ...props,
133
- forwardedRef: ref
134
- }));
135
- //#endregion
136
- export { FrameContext, FrameContextConsumer, FrameContextProvider, Frame_default as default, useFrame };
137
-
138
- //# sourceMappingURL=react-frame-component.esm.js.map
@@ -1 +0,0 @@
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 { Children, Component } from 'react';\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 // The listener was added to the iframe's content window in componentDidMount.\n this.nodeRef.current?.contentWindow?.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 // 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 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, contentDidUpdate } = this.props;\n\n const win = doc.defaultView || doc.parentView;\n // Reuse the context value across renders so consumers only re-render when the\n // document or window actually changes, not on every render of Frame.\n if (!this._contextValue || this._contextValue.document !== doc || this._contextValue.window !== win) {\n this._contextValue = { document: doc, window: win };\n }\n const contents = (\n <Content contentDidMount={contentDidMount} contentDidUpdate={contentDidUpdate}>\n <FrameContextProvider value={this._contextValue}>\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 [\n ReactDOM.createPortal(this.props.head, doc.head, 'head'),\n ReactDOM.createPortal(contents, mountTarget, 'contents'),\n ];\n }\n\n render() {\n // The iframe isn't ready so we drop children from the iframe props here. #12, #17\n const {\n children: _children,\n contentDidMount: _contentDidMount,\n contentDidUpdate: _contentDidUpdate,\n dangerouslyUseDocWrite,\n forwardedRef: _forwardedRef,\n head: _head,\n initialContent,\n mountTarget: _mountTarget,\n ...iframeProps\n } = this.props;\n\n if (!dangerouslyUseDocWrite) {\n iframeProps.srcDoc = initialContent;\n }\n\n return (\n // oxlint-disable-next-line jsx-a11y/iframe-has-title -- consumers can pass `title` via the props spread\n <iframe {...iframeProps} 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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"}
@@ -1,177 +0,0 @@
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?.contentWindow?.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
- if (!this.state.iframeLoaded) this.setState({ iframeLoaded: true });
123
- };
124
- renderFrameContents() {
125
- if (!this._isMounted) return;
126
- const doc = this.getDoc();
127
- if (!doc) return;
128
- const { contentDidMount, contentDidUpdate } = this.props;
129
- const win = doc.defaultView || doc.parentView;
130
- if (!this._contextValue || this._contextValue.document !== doc || this._contextValue.window !== win) this._contextValue = {
131
- document: doc,
132
- window: win
133
- };
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: this._contextValue,
139
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
140
- className: "frame-content",
141
- children: this.props.children
142
- })
143
- })
144
- });
145
- if (this.props.dangerouslyUseDocWrite && doc.body.children.length === 0) {
146
- doc.open("text/html", "replace");
147
- doc.write(this.props.initialContent);
148
- doc.close();
149
- }
150
- const mountTarget = this.getMountTarget();
151
- if (!mountTarget) return;
152
- return [react_dom.default.createPortal(this.props.head, doc.head, "head"), react_dom.default.createPortal(contents, mountTarget, "contents")];
153
- }
154
- render() {
155
- const { children: _children, contentDidMount: _contentDidMount, contentDidUpdate: _contentDidUpdate, dangerouslyUseDocWrite, forwardedRef: _forwardedRef, head: _head, initialContent, mountTarget: _mountTarget, ...iframeProps } = this.props;
156
- if (!dangerouslyUseDocWrite) iframeProps.srcDoc = initialContent;
157
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("iframe", {
158
- ...iframeProps,
159
- ref: this.setRef,
160
- onLoad: this.handleLoad,
161
- children: this.state.iframeLoaded && this.renderFrameContents()
162
- });
163
- }
164
- };
165
- var Frame_default = react.default.forwardRef((props, ref) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Frame, {
166
- ...props,
167
- forwardedRef: ref
168
- }));
169
- //#endregion
170
- exports.FrameContext = FrameContext;
171
- exports.FrameContextConsumer = FrameContextConsumer;
172
- exports.FrameContextProvider = FrameContextProvider;
173
- exports.default = Frame_default;
174
- exports.useFrame = useFrame;
175
- });
176
-
177
- //# sourceMappingURL=react-frame-component.umd.js.map
@@ -1 +0,0 @@
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 { Children, Component } from 'react';\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 // The listener was added to the iframe's content window in componentDidMount.\n this.nodeRef.current?.contentWindow?.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 // 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 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, contentDidUpdate } = this.props;\n\n const win = doc.defaultView || doc.parentView;\n // Reuse the context value across renders so consumers only re-render when the\n // document or window actually changes, not on every render of Frame.\n if (!this._contextValue || this._contextValue.document !== doc || this._contextValue.window !== win) {\n this._contextValue = { document: doc, window: win };\n }\n const contents = (\n <Content contentDidMount={contentDidMount} contentDidUpdate={contentDidUpdate}>\n <FrameContextProvider value={this._contextValue}>\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 [\n ReactDOM.createPortal(this.props.head, doc.head, 'head'),\n ReactDOM.createPortal(contents, mountTarget, 'contents'),\n ];\n }\n\n render() {\n // The iframe isn't ready so we drop children from the iframe props here. #12, #17\n const {\n children: _children,\n contentDidMount: _contentDidMount,\n contentDidUpdate: _contentDidUpdate,\n dangerouslyUseDocWrite,\n forwardedRef: _forwardedRef,\n head: _head,\n initialContent,\n mountTarget: _mountTarget,\n ...iframeProps\n } = this.props;\n\n if (!dangerouslyUseDocWrite) {\n iframeProps.srcDoc = initialContent;\n }\n\n return (\n // oxlint-disable-next-line jsx-a11y/iframe-has-title -- consumers can pass `title` via the props spread\n <iframe {...iframeProps} 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 DELETED
@@ -1,29 +0,0 @@
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 | undefined;
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;