Key improvements:
- Add `{@link}` cross-references throughout the codebase to make API
documentation navigable and help AI models understand relationships
- Use `{@link module!Export}` syntax for cross-module references
- Add backticks for inline code formatting (`ResizeObserver`, `App`, etc)
- Fix `PostMessageTransport` examples to show required two-argument form
- Clarify `onteardown` callback return type requirement
- Document React hooks cleanup behavior and Strict Mode considerations
- Add tool visibility example for `registerAppTool`
- Add CSP example for `registerAppResource`
- Fix notification direction documentation in `spec.types.ts`
TypeDoc config migrated from `typedoc.json` to `typedoc.config.mjs` to:
- Support custom `@description` block tag
- Add `intentionallyNotExported` for internal types
- Include `src/server/index.ts` entry point
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
71 lines
1.9 KiB
TypeScript
71 lines
1.9 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import { getDocumentTheme } from "../styles";
|
|
import { McpUiTheme } from "../types";
|
|
|
|
/**
|
|
* React hook that provides the current document theme reactively.
|
|
*
|
|
* Uses a `MutationObserver` to watch for changes to the `data-theme` attribute
|
|
* or `class` on `document.documentElement`. When the theme changes (e.g., from
|
|
* host context updates), the hook automatically re-renders your component with
|
|
* the new theme value.
|
|
*
|
|
* The `MutationObserver` is automatically disconnected when the component unmounts.
|
|
*
|
|
* @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>
|
|
* );
|
|
* }
|
|
* ```
|
|
*
|
|
* @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>
|
|
* );
|
|
* }
|
|
* ```
|
|
*
|
|
* @see {@link getDocumentTheme} for the underlying function
|
|
* @see {@link applyDocumentTheme} to set the theme
|
|
*/
|
|
export function useDocumentTheme(): McpUiTheme {
|
|
const [theme, setTheme] = useState<McpUiTheme>(getDocumentTheme);
|
|
|
|
useEffect(() => {
|
|
const observer = new MutationObserver(() => {
|
|
setTheme(getDocumentTheme());
|
|
});
|
|
|
|
observer.observe(document.documentElement, {
|
|
attributes: true,
|
|
attributeFilter: ["data-theme", "class"],
|
|
characterData: false,
|
|
childList: false,
|
|
subtree: false,
|
|
});
|
|
|
|
return () => observer.disconnect();
|
|
}, []);
|
|
|
|
return theme;
|
|
}
|