mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-04 07:33:18 +00:00
* feat(plugins): add React Native UI primitives Give client plugins host-owned adaptive UI without exposing app internals. Preserve plugin runtime contexts when modal content moves through the compact portal host. * docs(plugins): clarify host UI reference * refactor(plugins): harden host UI boundary Replace mocked pass-through coverage with a real browser plugin journey, keep host runtime ownership inside the evaluator, preserve toast context across compact portals, and expose modal content as a compound component. * fix(plugins): defer native UI presentation runtime Loading the plugin evaluator initialized the modal and toast presentation stacks even when no plugin requested host UI. Keep the capability stable while delaying platform-heavy presentation code until Modal.Content renders. * refactor(plugins): move modal metadata to root Keep Modal.Content body-only while the top-level Modal owns the host-rendered title and leading icon. This leaves presentation metadata stable as the compound API gains future regions.
37 lines
1.3 KiB
TypeScript
37 lines
1.3 KiB
TypeScript
import { createContext, useCallback, useContext, useMemo, type ReactNode } from "react";
|
|
import type { ZodType, input as ZodInput, output as ZodOutput } from "zod";
|
|
import { callPluginRpc, type PluginRpcContract } from "./rpc.js";
|
|
|
|
export interface PluginRpcContextValue {
|
|
invoke(method: string, input: unknown): Promise<unknown>;
|
|
}
|
|
|
|
const PluginRpcContext = createContext<PluginRpcContextValue | null>(null);
|
|
|
|
export function usePluginRpcContextValue(): PluginRpcContextValue | null {
|
|
return useContext(PluginRpcContext);
|
|
}
|
|
|
|
export function PluginRpcProvider({
|
|
children,
|
|
invoke,
|
|
}: {
|
|
children: ReactNode;
|
|
invoke(method: string, input: unknown): Promise<unknown>;
|
|
}) {
|
|
const value = useMemo(() => ({ invoke }), [invoke]);
|
|
return <PluginRpcContext.Provider value={value}>{children}</PluginRpcContext.Provider>;
|
|
}
|
|
|
|
export function useRpc<InputSchema extends ZodType, OutputSchema extends ZodType>(
|
|
contract: PluginRpcContract<InputSchema, OutputSchema>,
|
|
): (input: ZodInput<InputSchema>) => Promise<ZodOutput<OutputSchema>> {
|
|
const context = usePluginRpcContextValue();
|
|
if (!context) throw new Error("useRpc must run inside a contributed plugin surface");
|
|
|
|
return useCallback(
|
|
(input: ZodInput<InputSchema>) => callPluginRpc(contract, context.invoke, input),
|
|
[context, contract],
|
|
);
|
|
}
|