Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions packages/ui-react/src/context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,6 @@ interface AppsContextValueInternal {
error: Error | null;
}

// Public interface with generic type parameter for typed access
interface AppsContextValue<T extends ToolDefs = ToolDefs> {
client: AppsClient<T> | null;
isConnecting: boolean;
error: Error | null;
}

const AppsContext = createContext<AppsContextValueInternal | null>(null);

// =============================================================================
Expand Down Expand Up @@ -166,6 +159,15 @@ export function AppsProvider<T extends ToolDefs = ToolDefs>({
// INTERNAL HOOK
// =============================================================================

/**
* Context value exposed by useAppsContext
*/
export interface AppsContextValue<T extends ToolDefs = ToolDefs> {
client: AppsClient<T> | null;
isConnecting: boolean;
error: Error | null;
}

/**
* Internal hook to access the context
* @internal
Expand Down
47 changes: 27 additions & 20 deletions packages/ui-react/src/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -491,13 +491,25 @@ export function useOnToolInputPartial(handler: (input: Record<string, unknown>)
*/
export function useHostCapabilities(): HostCapabilities | undefined {
const { client } = useAppsContext();
const [capabilities, setCapabilities] = useState<HostCapabilities | undefined>(
const [capabilities, setCapabilities] = useState<HostCapabilities | undefined>(() =>
client?.getHostCapabilities()
);

useEffect(() => {
if (!client) return;
if (!client) {
setCapabilities(undefined);
return;
}

// Update capabilities initially
setCapabilities(client.getHostCapabilities());

// Subscribe to host context changes since capabilities can derive from context
const unsubscribe = client.onHostContextChange(() => {
setCapabilities(client.getHostCapabilities());
});

return unsubscribe;
}, [client]);

return capabilities;
Expand Down Expand Up @@ -527,10 +539,15 @@ export function useHostCapabilities(): HostCapabilities | undefined {
*/
export function useHostVersion(): HostVersion | undefined {
const { client } = useAppsContext();
const [version, setVersion] = useState<HostVersion | undefined>(client?.getHostVersion());
const [version, setVersion] = useState<HostVersion | undefined>(() => client?.getHostVersion());

useEffect(() => {
if (!client) return;
if (!client) {
setVersion(undefined);
return;
}

// Update version when client changes
setVersion(client.getHostVersion());
}, [client]);

Expand Down Expand Up @@ -666,13 +683,13 @@ export function useFileUpload(): UseFileUploadState & {
} {
const { client } = useAppsContext();
const [state, setState] = useState<UseFileUploadState>({
isSupported: false,
isSupported: !!client?.uploadFile,
isUploading: false,
error: null,
fileId: null,
});

// Check if upload is supported
// Update isSupported when client changes
useEffect(() => {
setState((prev) => ({
...prev,
Expand Down Expand Up @@ -758,13 +775,13 @@ export function useFileDownload(): {
error: Error | null;
downloadUrl: string | null;
}>({
isSupported: false,
isSupported: !!client?.getFileDownloadUrl,
isLoading: false,
error: null,
downloadUrl: null,
});

// Check if download URL is supported
// Update isSupported when client changes
useEffect(() => {
setState((prev) => ({
...prev,
Expand Down Expand Up @@ -857,12 +874,7 @@ export function useIntrinsicHeight(): {
} {
const { client } = useAppsContext();
const containerRef = useRef<HTMLElement | null>(null);
const [isSupported, setIsSupported] = useState(false);

// Check if supported
useEffect(() => {
setIsSupported(!!client?.notifyIntrinsicHeight);
}, [client]);
const isSupported = !!client?.notifyIntrinsicHeight;

// Manual notify function
const notify = useCallback(
Expand Down Expand Up @@ -1002,14 +1014,9 @@ export function useModal(): {
showModal: (options: ModalOptions) => Promise<ModalResult | null>;
} {
const { client } = useAppsContext();
const [isSupported, setIsSupported] = useState(false);
const isSupported = !!client?.requestModal;
const [isOpen, setIsOpen] = useState(false);

// Check if supported
useEffect(() => {
setIsSupported(!!client?.requestModal);
}, [client]);

const showModal = useCallback(
async (options: ModalOptions): Promise<ModalResult | null> => {
if (!client?.requestModal) {
Expand Down