Packages
React inside Phoenix LiveView — async code splitting, client-side props diffing, and zero-config component discovery.
Retired package: Release invalid - Not production-ready
Current section
Files
Jump to
Current section
Files
assets/types.ts
import type { ComponentType } from "react";
// ---------------------------------------------------------------------------
// Phoenix LiveView hook interface
// ---------------------------------------------------------------------------
/** Subset of the Phoenix LiveView JS hook that we rely on. */
export interface LiveViewHook {
el: HTMLElement;
viewName: string;
pushEvent(
event: string,
payload?: Record<string, unknown>,
onReply?: (reply: Record<string, unknown>) => void,
): void;
pushEventTo(
phxTarget: string | HTMLElement,
event: string,
payload?: Record<string, unknown>,
onReply?: (reply: Record<string, unknown>) => void,
): void;
handleEvent(
event: string,
callback: (payload: Record<string, unknown>) => void,
): string;
removeHandleEvent(callbackRef: string): void;
upload(name: string, files: FileList | File[]): void;
uploadTo(
target: string | HTMLElement,
name: string,
files: FileList | File[],
): void;
}
// ---------------------------------------------------------------------------
// Component resolution
// ---------------------------------------------------------------------------
/** A React component module — either a default export or a named export. */
export interface ComponentModule {
default?: ComponentType<any>;
[key: string]: ComponentType<any> | undefined;
}
/** A component or a promise that resolves to one. */
export type ComponentOrPromise =
| ComponentType<any>
| Promise<ComponentModule>;
/** A function that returns a component or promise given a name. */
export type ComponentLoader = (name: string) => ComponentOrPromise;
/** An async loader that returns a component module (e.g. `() => import("./Counter")`). */
export type AsyncComponentLoader = () => Promise<ComponentModule>;
/** A single entry in a component map — a component or an async loader. */
export type ComponentMapEntry = ComponentType<any> | AsyncComponentLoader;
/** A static (or lazy) map from component name to component or loader. */
export type ComponentMap = Record<string, ComponentMapEntry>;
/** A resolve function that returns a component (possibly async). */
export type ResolveFn = (name: string) => ComponentOrPromise;
/** Input for getHooks: either a static map or a resolve function. */
export type ComponentsOrResolve = ComponentMap | ResolveFn;
// ---------------------------------------------------------------------------
// Hook state
// ---------------------------------------------------------------------------
export type HookState = "loading" | "mounted" | "destroyed";
// ---------------------------------------------------------------------------
// Hook props — the functions injected into every React component
// ---------------------------------------------------------------------------
export interface HookProps {
pushEvent(
event: string,
payload?: Record<string, unknown>,
onReply?: (reply: Record<string, unknown>) => void,
): void;
pushEventTo(
phxTarget: string | HTMLElement,
event: string,
payload?: Record<string, unknown>,
onReply?: (reply: Record<string, unknown>) => void,
): void;
handleEvent(
event: string,
callback: (payload: Record<string, unknown>) => void,
): string;
removeHandleEvent(callbackRef: string): void;
upload(name: string, files: FileList | File[]): void;
uploadTo(
target: string | HTMLElement,
name: string,
files: FileList | File[],
): void;
}
// ---------------------------------------------------------------------------
// JSON Patch operation types (for future use)
// ---------------------------------------------------------------------------
export interface StandardPatchOp {
op: "add" | "remove" | "replace" | "move" | "copy" | "test";
path: string;
from?: string;
value?: unknown;
}
export interface UpsertOp {
op: "upsert";
path: string;
match: string;
value: unknown;
at?: number;
}
export interface DeleteByIdOp {
op: "delete_by_id";
path: string;
match: string;
}
export interface LimitOp {
op: "limit";
path: string;
value: number;
}
export type PatchOp = StandardPatchOp | UpsertOp | DeleteByIdOp | LimitOp;