react-iframe
Version:
A zero-dependency, typed, ref-forwarding iframe component for React 18+
105 lines (100 loc) • 4.22 kB
TypeScript
import * as react from 'react';
import { IframeHTMLAttributes, CSSProperties, RefObject } from 'react';
type SandboxToken = "allow-downloads" | "allow-downloads-without-user-activation" | "allow-forms" | "allow-modals" | "allow-orientation-lock" | "allow-pointer-lock" | "allow-popups" | "allow-popups-to-escape-sandbox" | "allow-presentation" | "allow-same-origin" | "allow-scripts" | "allow-storage-access-by-user-activation" | "allow-top-navigation" | "allow-top-navigation-by-user-activation" | "allow-top-navigation-to-custom-protocols";
type SandboxValue = SandboxToken | (string & {});
type FetchPriority = "high" | "low" | "auto";
type NativeIframeProps = Omit<IframeHTMLAttributes<HTMLIFrameElement>, "sandbox" | "src" | "srcDoc" | "onError">;
type LayoutShortcuts = {
/** Applied as `style.display` when set. */
display?: CSSProperties["display"];
/** Applied as `style.position` when set. */
position?: CSSProperties["position"];
/** Applied as `style.overflow` when set. */
overflow?: CSSProperties["overflow"];
/**
* Applied as `style.border` when set and neither `style.border` nor
* `styles.border` is provided. Prefer CSS `style={{ border: 0 }}`.
*/
frameBorder?: number | string;
};
type Conveniences = LayoutShortcuts & {
/**
* Alias for `src`. Ignored when `src` or `srcDoc` is set.
* Kept for 1.x compatibility.
*/
url?: string;
src?: string;
srcDoc?: string;
/** Merged into `style`. Inline `style` wins over `styles` over layout shortcuts. */
styles?: CSSProperties;
sandbox?: SandboxValue | readonly SandboxValue[];
fetchPriority?: FetchPriority;
/**
* Load the frame in a credentialless (ephemeral) context.
* React does not yet treat this as a boolean attribute, so `true` is
* emitted as the empty HTML boolean `credentialless=""`.
*/
credentialless?: boolean;
/**
* @deprecated Use `referrerPolicy`.
*/
referrerpolicy?: IframeHTMLAttributes<HTMLIFrameElement>["referrerPolicy"];
/**
* @deprecated Use `fetchPriority`.
*/
importance?: FetchPriority;
/**
* @deprecated Use `allow="payment"`.
*/
allowpaymentrequest?: boolean;
/**
* Native `error` event. React does not emit iframe `onError` as a
* synthetic event (only img / link / media).
*/
onError?: (event: Event) => void;
};
type WithUrl = {
url: string;
src?: string;
srcDoc?: string;
};
type WithSrc = {
src: string;
url?: string;
srcDoc?: string;
};
type WithSrcDoc = {
srcDoc: string;
url?: string;
src?: string;
};
type IframeProps = NativeIframeProps & Conveniences & (WithUrl | WithSrc | WithSrcDoc);
declare const Iframe: react.ForwardRefExoticComponent<IframeProps & react.RefAttributes<HTMLIFrameElement>>;
type IframeMessageSource = Window | HTMLIFrameElement | RefObject<HTMLIFrameElement | null | undefined>;
type UseIframeMessageOptions = {
/**
* When set, messages from other origins are ignored.
* A `srcDoc` frame has origin `"null"` (the string).
*/
origin?: string;
/**
* When set, messages whose `event.source` is not this frame's
* `contentWindow` are ignored. Prefer this over origin-only filtering
* when several frames share an origin.
*/
source?: IframeMessageSource | null;
};
/**
* Subscribe to `window` `"message"` events from framed documents.
* Pair with `postToIframe` or `ref.current.contentWindow.postMessage`.
*/
declare function useIframeMessage(handler: (event: MessageEvent) => void, options?: UseIframeMessageOptions): void;
/**
* Post a message to an iframe's `contentWindow`.
* Returns `false` when the iframe is missing or not yet ready.
*
* `targetOrigin` is required. Use the child's origin. For a `srcDoc`
* frame the origin is opaque and the browser rejects `"null"` — pass `"*"`.
*/
declare function postToIframe(iframe: HTMLIFrameElement | null | undefined, message: unknown, targetOrigin: string): boolean;
export { Iframe, type IframeMessageSource, type IframeProps, type SandboxToken, type SandboxValue, type UseIframeMessageOptions, Iframe as default, postToIframe, useIframeMessage };