Skip to content

Commit 7b9fd64

Browse files
committed
feat: add useFrame.
1 parent e40fb53 commit 7b9fd64

File tree

3 files changed

+78
-1
lines changed

3 files changed

+78
-1
lines changed

core/README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,57 @@ export default function Demo() {
134134
);
135135
}
136136
```
137+
138+
## Accessing the iframe's `window` and `document`
139+
140+
The iframe's `window` and `document` may be accessed via the `FrameContext.Consumer` or the useFrame hook.
141+
142+
```tsx mdx:preview
143+
import React, { useEffect, useState, Fragment } from 'react';
144+
import IFrame, { FrameContext } from '@uiw/react-iframe';
145+
146+
export default function Demo() {
147+
return (
148+
<IFrame>
149+
<FrameContext.Consumer>
150+
{({ document, window }) => {
151+
return (
152+
<div>
153+
<div>Hello World!</div>
154+
</div>
155+
)
156+
}}
157+
</FrameContext.Consumer>
158+
</IFrame>
159+
);
160+
}
161+
```
162+
163+
The example with `useFrame` hook:
164+
165+
```tsx mdx:preview
166+
import React, { useEffect, useState, Fragment } from 'react';
167+
import IFrame, { useFrame } from '@uiw/react-iframe';
168+
169+
const InnerComponent = () => {
170+
// Hook returns iframe's window and document instances from Frame context
171+
const { document, window } = useFrame();
172+
return (
173+
<div>
174+
<div>Hello World!</div>
175+
</div>
176+
);
177+
};
178+
179+
export default function Demo() {
180+
return (
181+
<IFrame>
182+
<InnerComponent />
183+
</IFrame>
184+
);
185+
}
186+
```
187+
137188
## Props
138189

139190
```ts

core/src/Context.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import React from 'react';
2+
3+
let doc;
4+
let win;
5+
if (typeof document !== 'undefined') {
6+
doc = document;
7+
}
8+
if (typeof window !== 'undefined') {
9+
win = window;
10+
}
11+
12+
export const FrameContext = React.createContext<ContextProps>({ document: doc, window: win });
13+
14+
interface ContextProps {
15+
document?: Document | null;
16+
window?: Window | null;
17+
}
18+
19+
export const useFrame = () => React.useContext<ContextProps>(FrameContext);

core/src/index.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { useCallback, useEffect, useState, forwardRef, useImperativeHandle } from 'react';
22
import { createPortal } from 'react-dom';
3+
import { FrameContext } from './Context';
4+
5+
export { FrameContext, useFrame } from './Context';
36

47
export interface IFrameProps
58
extends React.DetailedHTMLProps<React.IframeHTMLAttributes<HTMLIFrameElement>, HTMLIFrameElement> {
@@ -52,11 +55,15 @@ const IFrame = forwardRef<HTMLIFrameElement, IFrameProps>(
5255
}, [mountNode, handleLoad]);
5356

5457
const renderFrameContents = () => {
58+
const doc = getDoc();
5559
const header = getDoc()?.head;
5660
const mountTarget = getMountTarget();
61+
// @ts-ignore
62+
const win = doc?.defaultView || doc?.parentView;
63+
const contents = <FrameContext.Provider value={{ document: doc, window: win }}>{children}</FrameContext.Provider>;
5764
return [
5865
header && head && createPortal(head, header),
59-
mountNode && mountTarget && createPortal(children, mountTarget),
66+
mountNode && mountTarget && createPortal(contents, mountTarget),
6067
];
6168
};
6269
const reProps: IFrameProps = {};

0 commit comments

Comments
 (0)