UNPKG

@redocly/theme

Version:

Shared UI components lib

80 lines (66 loc) 2.07 kB
import { useState, useCallback, useMemo } from 'react'; import debounce from 'lodash.debounce'; import type { MCPOption } from '../types'; import { useThemeHooks } from './use-theme-hooks'; import { useMCPConfig } from './use-mcp-config'; import { ClipboardService } from '../utils/clipboard-service'; export type McpButtonOptions = { options?: MCPOption[]; }; export type McpButtonSettings = { isCopied: boolean; cursorUrl: string; vscodeUrl: string; triggerButtonText: string; visibleOptions: MCPOption[]; handleAction: (action: MCPOption) => void; }; const COPIED_RESET_TIMEOUT = 1000; export function useConnectMCPButton({ options = ['cursor', 'vscode', 'copy'], }: McpButtonOptions = {}): McpButtonSettings { const { useTranslate } = useThemeHooks(); const { translate } = useTranslate(); const { serverName, serverUrl, cursorUrl, vscodeUrl } = useMCPConfig(); const [isCopied, setIsCopied] = useState(false); // eslint-disable-next-line react-hooks/exhaustive-deps const resetCopied = useCallback( debounce(() => setIsCopied(false), COPIED_RESET_TIMEOUT), [], ); const handleAction = useCallback( (action: MCPOption) => { if (action === 'copy') { const config = { [serverName]: { url: serverUrl, description: 'MCP Server', }, }; ClipboardService.copyCustom(JSON.stringify(config, null, 2)); setIsCopied(true); resetCopied(); return; } const urlMap: Record<Exclude<MCPOption, 'copy'>, string> = { cursor: cursorUrl, vscode: vscodeUrl, }; window.open(urlMap[action], '_blank'); }, [cursorUrl, vscodeUrl, serverUrl, serverName, resetCopied], ); const triggerButtonText = useMemo( () => translate('page.actions.connectMcp', 'Connect MCP'), [translate], ); const visibleOptions = useMemo(() => options.filter(Boolean), [options]); return { isCopied, cursorUrl, vscodeUrl, triggerButtonText, visibleOptions, handleAction, }; }