Move JSDoc examples to type-checked .examples.ts files
Extract inline code examples from JSDoc comments into companion
`.examples.ts`/`.examples.tsx` files. Examples are now:
- Type-checked by wrapping them in functions
- Referenced via `{@includeCode ./file.examples.ts#regionName}` tags
- Organized using `//#region` and `//#endregion` markers
This keeps the main source files cleaner while ensuring examples
compile correctly. Updated TypeDoc config with `exampleTag: false`
to support title text on `@example` tags.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
e5c90c7385
commit
ad04e89745
10 changed files with 1661 additions and 838 deletions
26
src/react/index.examples.tsx
Normal file
26
src/react/index.examples.tsx
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* Type-checked examples for the React module overview.
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
|
||||
import { useApp } from "./index.js";
|
||||
|
||||
/**
|
||||
* Example: Basic React App from module overview.
|
||||
*/
|
||||
function index_basicReactApp() {
|
||||
//#region index_basicReactApp
|
||||
function MyApp() {
|
||||
const { app, isConnected, error } = useApp({
|
||||
appInfo: { name: "MyApp", version: "1.0.0" },
|
||||
capabilities: {},
|
||||
});
|
||||
|
||||
if (error) return <div>Error: {error.message}</div>;
|
||||
if (!isConnected) return <div>Connecting...</div>;
|
||||
|
||||
return <div>Connected!</div>;
|
||||
}
|
||||
//#endregion index_basicReactApp
|
||||
}
|
||||
|
|
@ -17,21 +17,7 @@
|
|||
* @module @modelcontextprotocol/ext-apps/react
|
||||
*
|
||||
* @example Basic React App
|
||||
* ```tsx
|
||||
* import { useApp } from '@modelcontextprotocol/ext-apps/react';
|
||||
*
|
||||
* function MyApp() {
|
||||
* const { app, isConnected, error } = useApp({
|
||||
* appInfo: { name: "MyApp", version: "1.0.0" },
|
||||
* capabilities: {}
|
||||
* });
|
||||
*
|
||||
* if (error) return <div>Error: {error.message}</div>;
|
||||
* if (!isConnected) return <div>Connecting...</div>;
|
||||
*
|
||||
* return <div>Connected!</div>;
|
||||
* }
|
||||
* ```
|
||||
* {@includeCode ./index.examples.tsx#index_basicReactApp}
|
||||
*/
|
||||
export * from "./useApp";
|
||||
export * from "./useAutoResize";
|
||||
|
|
|
|||
54
src/react/useApp.examples.tsx
Normal file
54
src/react/useApp.examples.tsx
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
* Type-checked examples for the useApp hook.
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
|
||||
import { useApp, McpUiToolInputNotificationSchema } from "./index.js";
|
||||
|
||||
/**
|
||||
* Example: Register a notification handler in onAppCreated.
|
||||
*/
|
||||
function useApp_registerHandler() {
|
||||
//#region useApp_registerHandler
|
||||
useApp({
|
||||
appInfo: { name: "MyApp", version: "1.0.0" },
|
||||
capabilities: {},
|
||||
onAppCreated: (app) => {
|
||||
app.setNotificationHandler(
|
||||
McpUiToolInputNotificationSchema,
|
||||
(notification) => {
|
||||
console.log("Tool input:", notification.params.arguments);
|
||||
},
|
||||
);
|
||||
},
|
||||
});
|
||||
//#endregion useApp_registerHandler
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Basic usage of useApp hook.
|
||||
*/
|
||||
function useApp_basicUsage() {
|
||||
//#region useApp_basicUsage
|
||||
function MyApp() {
|
||||
const { app, isConnected, error } = useApp({
|
||||
appInfo: { name: "MyApp", version: "1.0.0" },
|
||||
capabilities: {},
|
||||
onAppCreated: (app) => {
|
||||
// Register handlers before connection
|
||||
app.setNotificationHandler(
|
||||
McpUiToolInputNotificationSchema,
|
||||
(notification) => {
|
||||
console.log("Tool input:", notification.params.arguments);
|
||||
},
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
if (error) return <div>Error: {error.message}</div>;
|
||||
if (!isConnected) return <div>Connecting...</div>;
|
||||
return <div>Connected!</div>;
|
||||
}
|
||||
//#endregion useApp_basicUsage
|
||||
}
|
||||
|
|
@ -30,18 +30,7 @@ export interface UseAppOptions {
|
|||
* @param app - The newly created `App` instance
|
||||
*
|
||||
* @example Register a notification handler
|
||||
* ```typescript
|
||||
* import { McpUiToolInputNotificationSchema } from '@modelcontextprotocol/ext-apps/react';
|
||||
*
|
||||
* onAppCreated: (app) => {
|
||||
* app.setNotificationHandler(
|
||||
* McpUiToolInputNotificationSchema,
|
||||
* (notification) => {
|
||||
* console.log("Tool input:", notification.params.arguments);
|
||||
* }
|
||||
* );
|
||||
* }
|
||||
* ```
|
||||
* {@includeCode ./useApp.examples.tsx#useApp_registerHandler}
|
||||
*/
|
||||
onAppCreated?: (app: App) => void;
|
||||
}
|
||||
|
|
@ -81,29 +70,7 @@ export interface AppState {
|
|||
* timeouts, initialization handshake failures, or transport errors).
|
||||
*
|
||||
* @example Basic usage
|
||||
* ```typescript
|
||||
* import { useApp, McpUiToolInputNotificationSchema } from '@modelcontextprotocol/ext-apps/react';
|
||||
*
|
||||
* function MyApp() {
|
||||
* const { app, isConnected, error } = useApp({
|
||||
* appInfo: { name: "MyApp", version: "1.0.0" },
|
||||
* capabilities: {},
|
||||
* onAppCreated: (app) => {
|
||||
* // Register handlers before connection
|
||||
* app.setNotificationHandler(
|
||||
* McpUiToolInputNotificationSchema,
|
||||
* (notification) => {
|
||||
* console.log("Tool input:", notification.params.arguments);
|
||||
* }
|
||||
* );
|
||||
* },
|
||||
* });
|
||||
*
|
||||
* if (error) return <div>Error: {error.message}</div>;
|
||||
* if (!isConnected) return <div>Connecting...</div>;
|
||||
* return <div>Connected!</div>;
|
||||
* }
|
||||
* ```
|
||||
* {@includeCode ./useApp.examples.tsx#useApp_basicUsage}
|
||||
*
|
||||
* @see {@link App.connect} for the underlying connection method
|
||||
* @see {@link useAutoResize} for manual auto-resize control when using custom App options
|
||||
|
|
|
|||
42
src/react/useAutoResize.examples.tsx
Normal file
42
src/react/useAutoResize.examples.tsx
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* Type-checked examples for the useAutoResize hook.
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { App, PostMessageTransport } from "./index.js";
|
||||
import { useAutoResize } from "./useAutoResize.js";
|
||||
|
||||
/**
|
||||
* Example: Manual App creation with custom auto-resize control.
|
||||
*/
|
||||
function useAutoResize_manualApp() {
|
||||
//#region useAutoResize_manualApp
|
||||
function MyComponent() {
|
||||
// For custom App options, create App manually instead of using useApp
|
||||
const [app, setApp] = useState<App | null>(null);
|
||||
const [error, setError] = useState<Error | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const myApp = new App(
|
||||
{ name: "MyApp", version: "1.0.0" },
|
||||
{}, // capabilities
|
||||
{ autoResize: false }, // Disable default auto-resize
|
||||
);
|
||||
|
||||
const transport = new PostMessageTransport(window.parent, window.parent);
|
||||
myApp
|
||||
.connect(transport)
|
||||
.then(() => setApp(myApp))
|
||||
.catch((err) => setError(err));
|
||||
}, []);
|
||||
|
||||
// Add manual auto-resize control
|
||||
useAutoResize(app);
|
||||
|
||||
if (error) return <div>Connection failed: {error.message}</div>;
|
||||
return <div>My content</div>;
|
||||
}
|
||||
//#endregion useAutoResize_manualApp
|
||||
}
|
||||
|
|
@ -20,32 +20,7 @@ import { App } from "../app";
|
|||
* cause unnecessary effect re-runs; omit this parameter.
|
||||
*
|
||||
* @example Manual App creation with custom auto-resize control
|
||||
* ```tsx
|
||||
* function MyComponent() {
|
||||
* // For custom App options, create App manually instead of using useApp
|
||||
* const [app, setApp] = useState<App | null>(null);
|
||||
* const [error, setError] = useState<Error | null>(null);
|
||||
*
|
||||
* useEffect(() => {
|
||||
* const myApp = new App(
|
||||
* { name: "MyApp", version: "1.0.0" },
|
||||
* {}, // capabilities
|
||||
* { autoResize: false } // Disable default auto-resize
|
||||
* );
|
||||
*
|
||||
* const transport = new PostMessageTransport(window.parent, window.parent);
|
||||
* myApp.connect(transport)
|
||||
* .then(() => setApp(myApp))
|
||||
* .catch((err) => setError(err));
|
||||
* }, []);
|
||||
*
|
||||
* // Add manual auto-resize control
|
||||
* useAutoResize(app);
|
||||
*
|
||||
* if (error) return <div>Connection failed: {error.message}</div>;
|
||||
* return <div>My content</div>;
|
||||
* }
|
||||
* ```
|
||||
* {@includeCode ./useAutoResize.examples.tsx#useAutoResize_manualApp}
|
||||
*
|
||||
* @see {@link App.setupSizeChangedNotifications} for the underlying implementation
|
||||
* @see {@link useApp} which enables auto-resize by default
|
||||
|
|
|
|||
46
src/react/useDocumentTheme.examples.tsx
Normal file
46
src/react/useDocumentTheme.examples.tsx
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* Type-checked examples for the useDocumentTheme hook.
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
|
||||
import { useDocumentTheme } from "./useDocumentTheme.js";
|
||||
|
||||
// Stub components for examples
|
||||
declare function DarkIcon(): React.JSX.Element;
|
||||
declare function LightIcon(): React.JSX.Element;
|
||||
|
||||
/**
|
||||
* Example: Conditionally render based on theme.
|
||||
*/
|
||||
function useDocumentTheme_conditionalRender() {
|
||||
//#region useDocumentTheme_conditionalRender
|
||||
function MyApp() {
|
||||
const theme = useDocumentTheme();
|
||||
|
||||
return <div>{theme === "dark" ? <DarkIcon /> : <LightIcon />}</div>;
|
||||
}
|
||||
//#endregion useDocumentTheme_conditionalRender
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Use with theme-aware styling.
|
||||
*/
|
||||
function useDocumentTheme_themedButton() {
|
||||
//#region useDocumentTheme_themedButton
|
||||
function ThemedButton() {
|
||||
const theme = useDocumentTheme();
|
||||
|
||||
return (
|
||||
<button
|
||||
style={{
|
||||
background: theme === "dark" ? "#333" : "#fff",
|
||||
color: theme === "dark" ? "#fff" : "#333",
|
||||
}}
|
||||
>
|
||||
Click me
|
||||
</button>
|
||||
);
|
||||
}
|
||||
//#endregion useDocumentTheme_themedButton
|
||||
}
|
||||
|
|
@ -15,35 +15,10 @@ import { McpUiTheme } from "../types";
|
|||
* @returns The current theme ("light" or "dark")
|
||||
*
|
||||
* @example Conditionally render based on theme
|
||||
* ```tsx
|
||||
* import { useDocumentTheme } from '@modelcontextprotocol/ext-apps/react';
|
||||
*
|
||||
* function MyApp() {
|
||||
* const theme = useDocumentTheme();
|
||||
*
|
||||
* return (
|
||||
* <div>
|
||||
* {theme === 'dark' ? <DarkIcon /> : <LightIcon />}
|
||||
* </div>
|
||||
* );
|
||||
* }
|
||||
* ```
|
||||
* {@includeCode ./useDocumentTheme.examples.tsx#useDocumentTheme_conditionalRender}
|
||||
*
|
||||
* @example Use with theme-aware styling
|
||||
* ```tsx
|
||||
* function ThemedButton() {
|
||||
* const theme = useDocumentTheme();
|
||||
*
|
||||
* return (
|
||||
* <button style={{
|
||||
* background: theme === 'dark' ? '#333' : '#fff',
|
||||
* color: theme === 'dark' ? '#fff' : '#333',
|
||||
* }}>
|
||||
* Click me
|
||||
* </button>
|
||||
* );
|
||||
* }
|
||||
* ```
|
||||
* {@includeCode ./useDocumentTheme.examples.tsx#useDocumentTheme_themedButton}
|
||||
*
|
||||
* @see {@link getDocumentTheme} for the underlying function
|
||||
* @see {@link applyDocumentTheme} to set the theme
|
||||
|
|
|
|||
87
src/react/useHostStyles.examples.tsx
Normal file
87
src/react/useHostStyles.examples.tsx
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/**
|
||||
* Type-checked examples for the useHostStyles hooks.
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
|
||||
import { useState } from "react";
|
||||
import {
|
||||
useApp,
|
||||
useHostStyleVariables,
|
||||
useHostFonts,
|
||||
useHostStyles,
|
||||
App,
|
||||
} from "./index.js";
|
||||
import type { McpUiHostContext } from "../types.js";
|
||||
|
||||
/**
|
||||
* Example: Basic usage of useHostStyleVariables.
|
||||
*/
|
||||
function useHostStyleVariables_basicUsage() {
|
||||
//#region useHostStyleVariables_basicUsage
|
||||
function MyApp() {
|
||||
const { app, isConnected } = useApp({
|
||||
appInfo: { name: "MyApp", version: "1.0.0" },
|
||||
capabilities: {},
|
||||
});
|
||||
|
||||
// Apply host styles - pass initial context to apply styles from connect() immediately
|
||||
useHostStyleVariables(app, app?.getHostContext());
|
||||
|
||||
return (
|
||||
<div style={{ background: "var(--color-background-primary)" }}>
|
||||
Hello!
|
||||
</div>
|
||||
);
|
||||
}
|
||||
//#endregion useHostStyleVariables_basicUsage
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Basic usage of useHostFonts with useApp.
|
||||
*/
|
||||
function useHostFonts_basicUsage() {
|
||||
//#region useHostFonts_basicUsage
|
||||
function MyApp() {
|
||||
const { app, isConnected } = useApp({
|
||||
appInfo: { name: "MyApp", version: "1.0.0" },
|
||||
capabilities: {},
|
||||
});
|
||||
|
||||
// Automatically apply host fonts
|
||||
useHostFonts(app);
|
||||
|
||||
return <div style={{ fontFamily: "var(--font-sans)" }}>Hello!</div>;
|
||||
}
|
||||
//#endregion useHostFonts_basicUsage
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: useHostFonts with initial context.
|
||||
*/
|
||||
function useHostFonts_withInitialContext(app: App) {
|
||||
//#region useHostFonts_withInitialContext
|
||||
const [hostContext, setHostContext] = useState<McpUiHostContext | null>(null);
|
||||
|
||||
// ... get initial context from app.connect() result
|
||||
|
||||
useHostFonts(app, hostContext);
|
||||
//#endregion useHostFonts_withInitialContext
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Basic usage of useHostStyles.
|
||||
*/
|
||||
function useHostStyles_basicUsage() {
|
||||
const appInfo = { name: "MyApp", version: "1.0.0" };
|
||||
//#region useHostStyles_basicUsage
|
||||
function MyApp() {
|
||||
const { app } = useApp({ appInfo, capabilities: {} });
|
||||
useHostStyles(app, app?.getHostContext());
|
||||
|
||||
return (
|
||||
<div style={{ background: "var(--color-background-primary)" }}>...</div>
|
||||
);
|
||||
}
|
||||
//#endregion useHostStyles_basicUsage
|
||||
}
|
||||
|
|
@ -26,25 +26,7 @@ import { McpUiHostContext } from "../types";
|
|||
* If provided, styles and theme will be applied immediately on mount.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* import { useApp, useHostStyleVariables } from '@modelcontextprotocol/ext-apps/react';
|
||||
*
|
||||
* function MyApp() {
|
||||
* const { app, isConnected } = useApp({
|
||||
* appInfo: { name: "MyApp", version: "1.0.0" },
|
||||
* capabilities: {},
|
||||
* });
|
||||
*
|
||||
* // Apply host styles - pass initial context to apply styles from connect() immediately
|
||||
* useHostStyleVariables(app, app?.getHostContext());
|
||||
*
|
||||
* return (
|
||||
* <div style={{ background: 'var(--color-background-primary)' }}>
|
||||
* Hello!
|
||||
* </div>
|
||||
* );
|
||||
* }
|
||||
* ```
|
||||
* {@includeCode ./useHostStyles.examples.tsx#useHostStyleVariables_basicUsage}
|
||||
*
|
||||
* @see {@link applyHostStyleVariables} for the underlying styles function
|
||||
* @see {@link applyDocumentTheme} for the underlying theme function
|
||||
|
|
@ -107,35 +89,10 @@ export function useHostStyleVariables(
|
|||
* If provided, fonts will be applied immediately on mount.
|
||||
*
|
||||
* @example Basic usage with useApp
|
||||
* ```tsx
|
||||
* import { useApp } from '@modelcontextprotocol/ext-apps/react';
|
||||
* import { useHostFonts } from '@modelcontextprotocol/ext-apps/react';
|
||||
*
|
||||
* function MyApp() {
|
||||
* const { app, isConnected } = useApp({
|
||||
* appInfo: { name: "MyApp", version: "1.0.0" },
|
||||
* capabilities: {},
|
||||
* });
|
||||
*
|
||||
* // Automatically apply host fonts
|
||||
* useHostFonts(app);
|
||||
*
|
||||
* return (
|
||||
* <div style={{ fontFamily: 'var(--font-sans)' }}>
|
||||
* Hello!
|
||||
* </div>
|
||||
* );
|
||||
* }
|
||||
* ```
|
||||
* {@includeCode ./useHostStyles.examples.tsx#useHostFonts_basicUsage}
|
||||
*
|
||||
* @example With initial context
|
||||
* ```tsx
|
||||
* const [hostContext, setHostContext] = useState<McpUiHostContext | null>(null);
|
||||
*
|
||||
* // ... get initial context from app.connect() result
|
||||
*
|
||||
* useHostFonts(app, hostContext);
|
||||
* ```
|
||||
* {@includeCode ./useHostStyles.examples.tsx#useHostFonts_withInitialContext}
|
||||
*
|
||||
* @see {@link applyHostFonts} for the underlying fonts function
|
||||
* @see {@link useHostStyleVariables} for applying style variables and theme
|
||||
|
|
@ -182,14 +139,7 @@ export function useHostFonts(
|
|||
* Pass `app?.getHostContext()` to apply styles immediately on mount.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* function MyApp() {
|
||||
* const { app } = useApp({ appInfo, capabilities: {} });
|
||||
* useHostStyles(app, app?.getHostContext());
|
||||
*
|
||||
* return <div style={{ background: 'var(--color-background-primary)' }}>...</div>;
|
||||
* }
|
||||
* ```
|
||||
* {@includeCode ./useHostStyles.examples.tsx#useHostStyles_basicUsage}
|
||||
*
|
||||
* @see {@link useHostStyleVariables} for style variables and theme only
|
||||
* @see {@link useHostFonts} for fonts only
|
||||
|
|
|
|||
Loading…
Reference in a new issue