@seed-ship/mcp-ui-solid 6.19.0 → 6.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +532 -0
- package/README.md +798 -1
- package/dist/adapters/connector.cjs +15 -4
- package/dist/adapters/connector.cjs.map +1 -1
- package/dist/adapters/connector.d.ts +38 -0
- package/dist/adapters/connector.d.ts.map +1 -1
- package/dist/adapters/connector.js +15 -4
- package/dist/adapters/connector.js.map +1 -1
- package/dist/adapters/index.d.ts +4 -3
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/macro-run.cjs +25 -13
- package/dist/adapters/macro-run.cjs.map +1 -1
- package/dist/adapters/macro-run.d.ts +37 -2
- package/dist/adapters/macro-run.d.ts.map +1 -1
- package/dist/adapters/macro-run.js +25 -13
- package/dist/adapters/macro-run.js.map +1 -1
- package/dist/adapters.cjs +2 -0
- package/dist/adapters.cjs.map +1 -1
- package/dist/adapters.js +4 -2
- package/dist/components/ActionGroupRenderer.cjs +3 -1
- package/dist/components/ActionGroupRenderer.cjs.map +1 -1
- package/dist/components/ActionGroupRenderer.d.ts.map +1 -1
- package/dist/components/ActionGroupRenderer.js +3 -1
- package/dist/components/ActionGroupRenderer.js.map +1 -1
- package/dist/components/AgentCard.cjs +11 -8
- package/dist/components/AgentCard.cjs.map +1 -1
- package/dist/components/AgentCard.d.ts.map +1 -1
- package/dist/components/AgentCard.js +11 -8
- package/dist/components/AgentCard.js.map +1 -1
- package/dist/components/AgentHandoff.cjs +6 -1
- package/dist/components/AgentHandoff.cjs.map +1 -1
- package/dist/components/AgentHandoff.d.ts.map +1 -1
- package/dist/components/AgentHandoff.js +6 -1
- package/dist/components/AgentHandoff.js.map +1 -1
- package/dist/components/ArtifactRenderer.cjs +25 -6
- package/dist/components/ArtifactRenderer.cjs.map +1 -1
- package/dist/components/ArtifactRenderer.d.ts.map +1 -1
- package/dist/components/ArtifactRenderer.js +25 -6
- package/dist/components/ArtifactRenderer.js.map +1 -1
- package/dist/components/AutocompleteDropdown.cjs +30 -24
- package/dist/components/AutocompleteDropdown.cjs.map +1 -1
- package/dist/components/AutocompleteDropdown.d.ts.map +1 -1
- package/dist/components/AutocompleteDropdown.js +30 -24
- package/dist/components/AutocompleteDropdown.js.map +1 -1
- package/dist/components/AutocompleteFormField.cjs +3 -1
- package/dist/components/AutocompleteFormField.cjs.map +1 -1
- package/dist/components/AutocompleteFormField.d.ts.map +1 -1
- package/dist/components/AutocompleteFormField.js +4 -2
- package/dist/components/AutocompleteFormField.js.map +1 -1
- package/dist/components/BriefingDiff.cjs +45 -39
- package/dist/components/BriefingDiff.cjs.map +1 -1
- package/dist/components/BriefingDiff.d.ts.map +1 -1
- package/dist/components/BriefingDiff.js +45 -39
- package/dist/components/BriefingDiff.js.map +1 -1
- package/dist/components/CarouselRenderer.cjs +8 -2
- package/dist/components/CarouselRenderer.cjs.map +1 -1
- package/dist/components/CarouselRenderer.d.ts.map +1 -1
- package/dist/components/CarouselRenderer.js +8 -2
- package/dist/components/CarouselRenderer.js.map +1 -1
- package/dist/components/ChartJSRenderer.cjs +60 -36
- package/dist/components/ChartJSRenderer.cjs.map +1 -1
- package/dist/components/ChartJSRenderer.d.ts.map +1 -1
- package/dist/components/ChartJSRenderer.js +61 -37
- package/dist/components/ChartJSRenderer.js.map +1 -1
- package/dist/components/ChatPrompt.cjs +15 -9
- package/dist/components/ChatPrompt.cjs.map +1 -1
- package/dist/components/ChatPrompt.d.ts.map +1 -1
- package/dist/components/ChatPrompt.js +15 -9
- package/dist/components/ChatPrompt.js.map +1 -1
- package/dist/components/CodeBlockRenderer.cjs +34 -16
- package/dist/components/CodeBlockRenderer.cjs.map +1 -1
- package/dist/components/CodeBlockRenderer.d.ts.map +1 -1
- package/dist/components/CodeBlockRenderer.js +34 -16
- package/dist/components/CodeBlockRenderer.js.map +1 -1
- package/dist/components/DataPreviewSection.cjs +91 -44
- package/dist/components/DataPreviewSection.cjs.map +1 -1
- package/dist/components/DataPreviewSection.d.ts.map +1 -1
- package/dist/components/DataPreviewSection.js +92 -45
- package/dist/components/DataPreviewSection.js.map +1 -1
- package/dist/components/DegradedFallback.cjs +20 -16
- package/dist/components/DegradedFallback.cjs.map +1 -1
- package/dist/components/DegradedFallback.d.ts.map +1 -1
- package/dist/components/DegradedFallback.js +20 -16
- package/dist/components/DegradedFallback.js.map +1 -1
- package/dist/components/FeedbackInline.cjs +19 -3
- package/dist/components/FeedbackInline.cjs.map +1 -1
- package/dist/components/FeedbackInline.js +19 -3
- package/dist/components/FeedbackInline.js.map +1 -1
- package/dist/components/FooterRenderer.cjs +21 -17
- package/dist/components/FooterRenderer.cjs.map +1 -1
- package/dist/components/FooterRenderer.d.ts.map +1 -1
- package/dist/components/FooterRenderer.js +21 -17
- package/dist/components/FooterRenderer.js.map +1 -1
- package/dist/components/FormFieldRenderer.cjs +116 -93
- package/dist/components/FormFieldRenderer.cjs.map +1 -1
- package/dist/components/FormFieldRenderer.d.ts.map +1 -1
- package/dist/components/FormFieldRenderer.js +116 -93
- package/dist/components/FormFieldRenderer.js.map +1 -1
- package/dist/components/FormRenderer.cjs +55 -31
- package/dist/components/FormRenderer.cjs.map +1 -1
- package/dist/components/FormRenderer.d.ts.map +1 -1
- package/dist/components/FormRenderer.js +55 -31
- package/dist/components/FormRenderer.js.map +1 -1
- package/dist/components/GenerativeUIErrorBoundary.cjs +20 -15
- package/dist/components/GenerativeUIErrorBoundary.cjs.map +1 -1
- package/dist/components/GenerativeUIErrorBoundary.d.ts.map +1 -1
- package/dist/components/GenerativeUIErrorBoundary.js +20 -15
- package/dist/components/GenerativeUIErrorBoundary.js.map +1 -1
- package/dist/components/GraphRenderer.cjs +56 -33
- package/dist/components/GraphRenderer.cjs.map +1 -1
- package/dist/components/GraphRenderer.d.ts.map +1 -1
- package/dist/components/GraphRenderer.js +56 -33
- package/dist/components/GraphRenderer.js.map +1 -1
- package/dist/components/ImageGalleryRenderer.cjs +13 -4
- package/dist/components/ImageGalleryRenderer.cjs.map +1 -1
- package/dist/components/ImageGalleryRenderer.d.ts.map +1 -1
- package/dist/components/ImageGalleryRenderer.js +13 -4
- package/dist/components/ImageGalleryRenderer.js.map +1 -1
- package/dist/components/LightboxOverlay.cjs +16 -8
- package/dist/components/LightboxOverlay.cjs.map +1 -1
- package/dist/components/LightboxOverlay.d.ts.map +1 -1
- package/dist/components/LightboxOverlay.js +17 -9
- package/dist/components/LightboxOverlay.js.map +1 -1
- package/dist/components/MapRenderer.cjs +59 -29
- package/dist/components/MapRenderer.cjs.map +1 -1
- package/dist/components/MapRenderer.d.ts +10 -2
- package/dist/components/MapRenderer.d.ts.map +1 -1
- package/dist/components/MapRenderer.js +60 -30
- package/dist/components/MapRenderer.js.map +1 -1
- package/dist/components/ModalRenderer.cjs +4 -1
- package/dist/components/ModalRenderer.cjs.map +1 -1
- package/dist/components/ModalRenderer.d.ts.map +1 -1
- package/dist/components/ModalRenderer.js +5 -2
- package/dist/components/ModalRenderer.js.map +1 -1
- package/dist/components/ScratchpadPanel.cjs +578 -535
- package/dist/components/ScratchpadPanel.cjs.map +1 -1
- package/dist/components/ScratchpadPanel.d.ts.map +1 -1
- package/dist/components/ScratchpadPanel.js +578 -535
- package/dist/components/ScratchpadPanel.js.map +1 -1
- package/dist/components/StreamingUIRenderer.cjs +92 -28
- package/dist/components/StreamingUIRenderer.cjs.map +1 -1
- package/dist/components/StreamingUIRenderer.d.ts.map +1 -1
- package/dist/components/StreamingUIRenderer.js +92 -28
- package/dist/components/StreamingUIRenderer.js.map +1 -1
- package/dist/components/UIResourceRenderer.cjs +456 -363
- package/dist/components/UIResourceRenderer.cjs.map +1 -1
- package/dist/components/UIResourceRenderer.d.ts +21 -0
- package/dist/components/UIResourceRenderer.d.ts.map +1 -1
- package/dist/components/UIResourceRenderer.js +458 -365
- package/dist/components/UIResourceRenderer.js.map +1 -1
- package/dist/components/VerifiedText.cjs +39 -20
- package/dist/components/VerifiedText.cjs.map +1 -1
- package/dist/components/VerifiedText.d.ts +2 -1
- package/dist/components/VerifiedText.d.ts.map +1 -1
- package/dist/components/VerifiedText.js +39 -20
- package/dist/components/VerifiedText.js.map +1 -1
- package/dist/components/VideoRenderer.cjs +10 -5
- package/dist/components/VideoRenderer.cjs.map +1 -1
- package/dist/components/VideoRenderer.d.ts.map +1 -1
- package/dist/components/VideoRenderer.js +10 -5
- package/dist/components/VideoRenderer.js.map +1 -1
- package/dist/components/chart-data-table.cjs +38 -17
- package/dist/components/chart-data-table.cjs.map +1 -1
- package/dist/components/chart-data-table.d.ts +30 -1
- package/dist/components/chart-data-table.d.ts.map +1 -1
- package/dist/components/chart-data-table.js +38 -17
- package/dist/components/chart-data-table.js.map +1 -1
- package/dist/context/MCPActionContext.cjs +3 -1
- package/dist/context/MCPActionContext.cjs.map +1 -1
- package/dist/context/MCPActionContext.d.ts.map +1 -1
- package/dist/context/MCPActionContext.js +3 -1
- package/dist/context/MCPActionContext.js.map +1 -1
- package/dist/context/MCPUIStringsContext.cjs +285 -2
- package/dist/context/MCPUIStringsContext.cjs.map +1 -1
- package/dist/context/MCPUIStringsContext.d.ts +600 -3
- package/dist/context/MCPUIStringsContext.d.ts.map +1 -1
- package/dist/context/MCPUIStringsContext.js +285 -2
- package/dist/context/MCPUIStringsContext.js.map +1 -1
- package/dist/hooks/index.d.ts +2 -2
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/useStreamingUI.cjs +28 -10
- package/dist/hooks/useStreamingUI.cjs.map +1 -1
- package/dist/hooks/useStreamingUI.d.ts +37 -0
- package/dist/hooks/useStreamingUI.d.ts.map +1 -1
- package/dist/hooks/useStreamingUI.js +28 -10
- package/dist/hooks/useStreamingUI.js.map +1 -1
- package/dist/hooks.cjs +1 -0
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.js +2 -1
- package/dist/index.cjs +23 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -3
- package/dist/index.js.map +1 -1
- package/dist/services/validation.cjs +41 -16
- package/dist/services/validation.cjs.map +1 -1
- package/dist/services/validation.d.ts +47 -2
- package/dist/services/validation.d.ts.map +1 -1
- package/dist/services/validation.js +41 -16
- package/dist/services/validation.js.map +1 -1
- package/dist/utils/degraded-projections.cjs +37 -12
- package/dist/utils/degraded-projections.cjs.map +1 -1
- package/dist/utils/degraded-projections.d.ts +39 -3
- package/dist/utils/degraded-projections.d.ts.map +1 -1
- package/dist/utils/degraded-projections.js +37 -12
- package/dist/utils/degraded-projections.js.map +1 -1
- package/dist/utils/format-string.cjs +10 -0
- package/dist/utils/format-string.cjs.map +1 -0
- package/dist/utils/format-string.d.ts +26 -0
- package/dist/utils/format-string.d.ts.map +1 -0
- package/dist/utils/format-string.js +10 -0
- package/dist/utils/format-string.js.map +1 -0
- package/dist/validation.cjs +3 -0
- package/dist/validation.cjs.map +1 -1
- package/dist/validation.d.cts +2 -1
- package/dist/validation.d.ts +2 -1
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +4 -1
- package/package.json +1 -1
- package/src/adapters/connector.ts +58 -4
- package/src/adapters/index.ts +12 -2
- package/src/adapters/macro-run.ts +71 -11
- package/src/components/ActionGroupRenderer.tsx +3 -1
- package/src/components/AgentCard.tsx +27 -9
- package/src/components/AgentHandoff.tsx +4 -1
- package/src/components/ArtifactRenderer.tsx +17 -5
- package/src/components/AutocompleteDropdown.tsx +8 -6
- package/src/components/AutocompleteFormField.tsx +5 -1
- package/src/components/BriefingDiff.tsx +11 -3
- package/src/components/CarouselRenderer.tsx +4 -2
- package/src/components/ChartJSRenderer.tsx +18 -9
- package/src/components/ChatPrompt.tsx +13 -8
- package/src/components/CodeBlockRenderer.tsx +12 -10
- package/src/components/DataPreviewSection.tsx +92 -26
- package/src/components/DegradedFallback.tsx +4 -2
- package/src/components/FeedbackInline.tsx +2 -2
- package/src/components/FooterRenderer.tsx +3 -1
- package/src/components/FormFieldRenderer.tsx +34 -19
- package/src/components/FormRenderer.tsx +38 -10
- package/src/components/GenerativeUIErrorBoundary.tsx +8 -3
- package/src/components/GraphRenderer.tsx +31 -16
- package/src/components/ImageGalleryRenderer.tsx +8 -4
- package/src/components/LightboxOverlay.tsx +6 -4
- package/src/components/MapRenderer.tsx +57 -20
- package/src/components/ModalRenderer.tsx +3 -1
- package/src/components/ScratchpadPanel.tsx +95 -44
- package/src/components/StreamingUIRenderer.tsx +41 -11
- package/src/components/UIResourceRenderer.tsx +145 -63
- package/src/components/VerifiedText.tsx +19 -9
- package/src/components/VideoRenderer.tsx +6 -4
- package/src/components/chart-data-table.ts +68 -14
- package/src/context/MCPActionContext.tsx +4 -1
- package/src/context/MCPUIStringsContext.tsx +1004 -1
- package/src/hooks/index.ts +2 -1
- package/src/hooks/useStreamingUI.ts +64 -10
- package/src/index.ts +23 -0
- package/src/services/validation.ts +93 -16
- package/src/utils/degraded-projections.ts +75 -12
- package/src/utils/format-string.ts +33 -0
- package/src/validation.ts +5 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeBlockRenderer.cjs","sources":["../../src/components/CodeBlockRenderer.tsx"],"sourcesContent":["/**\n * CodeBlockRenderer - Syntax highlighted code block\n * Sprint 6: Code & Maps\n * Sprint Ultimate: Theme Synchronization (U.1)\n */\n\nimport { Component, createEffect, onCleanup, createSignal, Show, For } from 'solid-js'\nimport { isServer } from 'solid-js/web'\nimport type { UIComponent, CodeComponentParams } from '../types'\nimport { ExpandableWrapper, useExpanded } from './ExpandableWrapper'\nimport { highlightQuery } from './UIResourceRenderer'\nimport { escapeHtml } from '../utils/escape-html'\n\n/** Map of `params.language` → file extension for the v6.2.0 download button. */\nconst LANGUAGE_EXTENSIONS: Record<string, string> = {\n typescript: 'ts', tsx: 'tsx', javascript: 'js', jsx: 'jsx',\n python: 'py', ruby: 'rb', go: 'go', rust: 'rs', java: 'java',\n kotlin: 'kt', swift: 'swift', php: 'php', csharp: 'cs', cpp: 'cpp',\n c: 'c', sql: 'sql', json: 'json', yaml: 'yml', toml: 'toml',\n bash: 'sh', shell: 'sh', html: 'html', css: 'css', scss: 'scss',\n markdown: 'md', xml: 'xml', graphql: 'graphql',\n}\n\n// Lazy load highlight.js\nlet hljs: any = null\n// Track if styles have been loaded globally\nlet stylesLoaded = false\n\nexport interface CodeBlockRendererProps {\n /**\n * UIComponent containing code params\n */\n component?: UIComponent\n\n /**\n * Direct code params\n */\n params?: CodeComponentParams\n\n /**\n * Forwarded to the underlying `<ExpandableWrapper>` (v6.3.1).\n * @see ExpandableWrapperProps.toolbarVariant\n */\n toolbarVariant?: 'hover' | 'always-visible'\n}\n\nexport const CodeBlockRenderer: Component<CodeBlockRendererProps> = (props) => {\n const [highlightedCode, setHighlightedCode] = createSignal<string>('')\n const [isCopied, setIsCopied] = createSignal(false)\n const [isHljsLoaded, setIsHljsLoaded] = createSignal(false)\n const [activeTheme, setActiveTheme] = createSignal<'light' | 'dark'>('dark')\n const [wordWrap, setWordWrap] = createSignal(false)\n\n const params = () => props.params || (props.component?.params as CodeComponentParams)\n const isExpanded = useExpanded()\n const [searchQuery, setSearchQuery] = createSignal('')\n\n // v6.2.0 — search highlight: re-wraps `<mark>` around matches in the\n // already-highlighted (hljs) HTML output. `highlightQuery` is the same\n // helper TableRenderer uses (only wraps text outside of HTML tags so\n // syntax span colors stay intact).\n const displayedHTML = () => {\n const q = searchQuery().trim()\n return q ? highlightQuery(highlightedCode(), q) : highlightedCode()\n }\n\n const handleDownload = () => {\n const code = params()?.code\n if (!code) return\n const lang = (params()?.language || '').toLowerCase()\n const ext = LANGUAGE_EXTENSIONS[lang] || 'txt'\n const stem = (params()?.filename || `code-${Date.now()}`).replace(/\\.[^.]+$/, '')\n const filename = stem.endsWith(`.${ext}`) ? stem : `${stem}.${ext}`\n const blob = new Blob([code], { type: 'text/plain' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = filename\n document.body.appendChild(a)\n a.click()\n document.body.removeChild(a)\n URL.revokeObjectURL(url)\n }\n\n // Load highlight.js on mount\n createEffect(async () => {\n if (!hljs) {\n try {\n // Use the full highlight.js bundle with all languages for simplicity\n const module = await import('highlight.js')\n const resolved = module.default || module\n // Guard: verify the resolved module has the expected API\n if (typeof resolved?.highlight === 'function') {\n hljs = resolved\n } else {\n console.warn('highlight.js loaded but missing highlight() method')\n }\n setIsHljsLoaded(true)\n } catch (e) {\n console.warn('Failed to load highlight.js', e)\n // Continue without highlighting - fallback to plain text\n setIsHljsLoaded(true)\n }\n } else {\n setIsHljsLoaded(true)\n }\n })\n\n // Theme management - Sprint Ultimate U.1: Reactive theme synchronization\n // Load both theme stylesheets once, then toggle via data-attribute\n createEffect(async () => {\n if (isServer || stylesLoaded) return\n\n // Load both themes upfront for instant switching\n try {\n await Promise.all([\n import('highlight.js/styles/github.css'),\n import('highlight.js/styles/github-dark.css')\n ])\n stylesLoaded = true\n } catch (e) {\n console.warn('Failed to load highlight.js themes', e)\n }\n })\n\n // Reactive theme detection - listens to system preference changes\n createEffect(() => {\n if (isServer) return\n\n // Priority 1: Explicit theme from params\n const paramTheme = params()?.theme\n if (paramTheme) {\n setActiveTheme(paramTheme)\n return\n }\n\n // Priority 2: System preference with live updates\n // Check if matchMedia is available (not in all test environments)\n if (typeof window !== 'undefined' && typeof window.matchMedia === 'function') {\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')\n setActiveTheme(mediaQuery.matches ? 'dark' : 'light')\n\n const handleChange = (e: MediaQueryListEvent) => {\n // Only update if no explicit theme in params\n if (!params()?.theme) {\n setActiveTheme(e.matches ? 'dark' : 'light')\n }\n }\n\n mediaQuery.addEventListener('change', handleChange)\n onCleanup(() => mediaQuery.removeEventListener('change', handleChange))\n }\n })\n\n // Apply highlighting\n createEffect(() => {\n const code = params()?.code || ''\n const language = params()?.language || ''\n\n if (hljs && isHljsLoaded()) {\n try {\n let result\n if (language && hljs.getLanguage(language)) {\n result = hljs.highlight(code, { language }).value\n } else {\n result = hljs.highlightAuto(code).value\n }\n setHighlightedCode(result)\n } catch (e) {\n setHighlightedCode(escapeHtml(code))\n }\n } else {\n // Fallback: no highlight.js → the raw source goes straight to an\n // `innerHTML` sink, so it must be fully escaped. The previous\n // hand-rolled `< >`-only replace left `&` unescaped, which made\n // code containing `<script>` render as a literal tag.\n setHighlightedCode(escapeHtml(code))\n }\n })\n\n // Line numbers generation\n const lineNumbers = () => {\n if (params()?.showLineNumbers === false) return []\n const code = params()?.code || ''\n const lines = code.split('\\n')\n const start = params()?.startLine || 1\n return lines.map((_, i) => start + i)\n }\n\n const handleCopy = async () => {\n const code = params()?.code\n if (code) {\n try {\n await navigator.clipboard.writeText(code)\n setIsCopied(true)\n setTimeout(() => setIsCopied(false), 2000)\n } catch (e) {\n console.error('Failed to copy code', e)\n }\n }\n }\n\n return (\n <ExpandableWrapper title={params()?.filename || params()?.language || 'Code'} copyData={params()?.code} copyLabel=\"Copy code\" toolbarVariant={props.toolbarVariant}>\n <div class={`w-full bg-gray-50 dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden text-sm flex flex-col ${isExpanded() ? 'flex-1 min-h-0' : ''}`}>\n {/* Header */}\n <div class=\"flex items-center justify-between px-4 py-2 bg-gray-100 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 shrink-0\">\n <div class=\"font-mono text-xs text-gray-600 dark:text-gray-400\">\n {params()?.filename || params()?.language || 'Code'}\n </div>\n <div class=\"flex items-center gap-2\">\n {/* Search input (v6.2.0) */}\n <input\n type=\"text\"\n value={searchQuery()}\n onInput={(e) => setSearchQuery(e.currentTarget.value)}\n placeholder=\"Search…\"\n class=\"px-2 py-0.5 text-xs border border-gray-200 dark:border-gray-600 rounded bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-400 focus:border-blue-400 focus:ring-1 focus:ring-blue-400 outline-none w-32\"\n aria-label=\"Search in code\"\n />\n {/* Download button (v6.2.0) */}\n <button\n onClick={handleDownload}\n class=\"text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 focus:outline-none transition-colors\"\n aria-label=\"Download code as file\"\n title=\"Download code\"\n >\n <svg class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\" />\n </svg>\n </button>\n {/* Word wrap toggle */}\n <button\n onClick={() => setWordWrap(!wordWrap())}\n class={`focus:outline-none transition-colors ${wordWrap() ? 'text-blue-500 dark:text-blue-400' : 'text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200'}`}\n aria-label=\"Toggle word wrap\"\n title={wordWrap() ? 'Disable word wrap' : 'Enable word wrap'}\n >\n <svg class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M3 10h10a4 4 0 010 8H9m4 0l-3-3m3 3l-3 3M3 6h18M3 14h4\" />\n </svg>\n </button>\n {/* Copy button */}\n <button\n onClick={handleCopy}\n class=\"text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 focus:outline-none transition-colors\"\n aria-label=\"Copy code\"\n title=\"Copy code\"\n >\n <Show when={isCopied()} fallback={\n <svg class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\" />\n </svg>\n }>\n <svg class=\"w-4 h-4 text-green-500\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13l4 4L19 7\" />\n </svg>\n </Show>\n </button>\n </div>\n </div>\n\n {/* Code Area */}\n <div\n class={`relative overflow-auto flex ${isExpanded() ? 'flex-1 min-h-0' : ''}`}\n style={!isExpanded() && params()?.maxHeight ? { 'max-height': params()?.maxHeight } : {}}\n >\n {/* Line Numbers */}\n <Show when={params()?.showLineNumbers !== false}>\n <div class=\"flex-none text-right select-none bg-gray-100 dark:bg-gray-800 border-r border-gray-200 dark:border-gray-700 py-4 px-2 text-gray-400 font-mono text-xs leading-5\">\n <For each={lineNumbers()}>\n {(num) => <div class=\"px-2\">{num}</div>}\n </For>\n </div>\n </Show>\n\n {/* Code Content - Sprint Ultimate U.1: data-theme for reactive theming */}\n <pre\n class=\"flex-1 m-0 p-4 font-mono text-gray-800 dark:text-gray-100 bg-transparent leading-5\"\n style={wordWrap() ? { 'white-space': 'pre-wrap', 'word-break': 'break-all' } : {}}\n data-theme={activeTheme()}\n >\n <code\n class={`hljs ${params()?.language ? `language-${params()?.language}` : ''}`}\n innerHTML={displayedHTML()}\n />\n </pre>\n </div>\n </div>\n </ExpandableWrapper>\n )\n}\n"],"names":["LANGUAGE_EXTENSIONS","typescript","tsx","javascript","jsx","python","ruby","go","rust","java","kotlin","swift","php","csharp","cpp","c","sql","json","yaml","toml","bash","shell","html","css","scss","markdown","xml","graphql","hljs","stylesLoaded","CodeBlockRenderer","props","highlightedCode","setHighlightedCode","createSignal","isCopied","setIsCopied","isHljsLoaded","setIsHljsLoaded","activeTheme","setActiveTheme","wordWrap","setWordWrap","params","component","isExpanded","useExpanded","searchQuery","setSearchQuery","displayedHTML","q","trim","highlightQuery","handleDownload","code","lang","language","toLowerCase","ext","stem","filename","Date","now","replace","endsWith","blob","Blob","type","url","URL","createObjectURL","a","document","createElement","href","download","body","appendChild","click","removeChild","revokeObjectURL","createEffect","module","resolved","default","highlight","console","warn","e","isServer","Promise","all","paramTheme","theme","window","matchMedia","mediaQuery","matches","handleChange","addEventListener","onCleanup","removeEventListener","result","getLanguage","value","highlightAuto","escapeHtml","lineNumbers","showLineNumbers","lines","split","start","startLine","map","_","i","handleCopy","navigator","clipboard","writeText","setTimeout","error","_$createComponent","ExpandableWrapper","title","copyData","copyLabel","toolbarVariant","children","_el$","_$getNextElement","_tmpl$3","_el$2","firstChild","_el$3","_el$4","nextSibling","_el$5","_el$6","_el$7","_el$8","_el$0","_el$12","_el$13","_co$","_$getNextMarker","_el$10","_el$11","_$insert","$$input","currentTarget","$$click","Show","when","fallback","_tmpl$4","_tmpl$","_el$1","_tmpl$2","For","each","num","_el$15","_tmpl$5","_$effect","_p$","_v$","_v$2","_v$3","_v$4","_v$5","maxHeight","_v$6","_v$7","_v$8","_v$9","_$className","t","_$setAttribute","o","_$style","n","s","h","r","_$setProperty","undefined","_$runHydrationEvents","_$delegateEvents"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CodeBlockRenderer.cjs","sources":["../../src/components/CodeBlockRenderer.tsx"],"sourcesContent":["/**\n * CodeBlockRenderer - Syntax highlighted code block\n * Sprint 6: Code & Maps\n * Sprint Ultimate: Theme Synchronization (U.1)\n */\n\nimport { Component, createEffect, onCleanup, createSignal, Show, For } from 'solid-js'\nimport { isServer } from 'solid-js/web'\nimport type { UIComponent, CodeComponentParams } from '../types'\nimport { ExpandableWrapper, useExpanded } from './ExpandableWrapper'\nimport { highlightQuery } from './UIResourceRenderer'\nimport { escapeHtml } from '../utils/escape-html'\nimport { useMCPUIStrings } from '../context/MCPUIStringsContext'\n\n/** Map of `params.language` → file extension for the v6.2.0 download button. */\nconst LANGUAGE_EXTENSIONS: Record<string, string> = {\n typescript: 'ts', tsx: 'tsx', javascript: 'js', jsx: 'jsx',\n python: 'py', ruby: 'rb', go: 'go', rust: 'rs', java: 'java',\n kotlin: 'kt', swift: 'swift', php: 'php', csharp: 'cs', cpp: 'cpp',\n c: 'c', sql: 'sql', json: 'json', yaml: 'yml', toml: 'toml',\n bash: 'sh', shell: 'sh', html: 'html', css: 'css', scss: 'scss',\n markdown: 'md', xml: 'xml', graphql: 'graphql',\n}\n\n// Lazy load highlight.js\nlet hljs: any = null\n// Track if styles have been loaded globally\nlet stylesLoaded = false\n\nexport interface CodeBlockRendererProps {\n /**\n * UIComponent containing code params\n */\n component?: UIComponent\n\n /**\n * Direct code params\n */\n params?: CodeComponentParams\n\n /**\n * Forwarded to the underlying `<ExpandableWrapper>` (v6.3.1).\n * @see ExpandableWrapperProps.toolbarVariant\n */\n toolbarVariant?: 'hover' | 'always-visible'\n}\n\nexport const CodeBlockRenderer: Component<CodeBlockRendererProps> = (props) => {\n const strings = useMCPUIStrings()\n const [highlightedCode, setHighlightedCode] = createSignal<string>('')\n const [isCopied, setIsCopied] = createSignal(false)\n const [isHljsLoaded, setIsHljsLoaded] = createSignal(false)\n const [activeTheme, setActiveTheme] = createSignal<'light' | 'dark'>('dark')\n const [wordWrap, setWordWrap] = createSignal(false)\n\n const params = () => props.params || (props.component?.params as CodeComponentParams)\n const isExpanded = useExpanded()\n const [searchQuery, setSearchQuery] = createSignal('')\n\n // v6.2.0 — search highlight: re-wraps `<mark>` around matches in the\n // already-highlighted (hljs) HTML output. `highlightQuery` is the same\n // helper TableRenderer uses (only wraps text outside of HTML tags so\n // syntax span colors stay intact).\n const displayedHTML = () => {\n const q = searchQuery().trim()\n return q ? highlightQuery(highlightedCode(), q) : highlightedCode()\n }\n\n const handleDownload = () => {\n const code = params()?.code\n if (!code) return\n const lang = (params()?.language || '').toLowerCase()\n const ext = LANGUAGE_EXTENSIONS[lang] || 'txt'\n const stem = (params()?.filename || `code-${Date.now()}`).replace(/\\.[^.]+$/, '')\n const filename = stem.endsWith(`.${ext}`) ? stem : `${stem}.${ext}`\n const blob = new Blob([code], { type: 'text/plain' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = filename\n document.body.appendChild(a)\n a.click()\n document.body.removeChild(a)\n URL.revokeObjectURL(url)\n }\n\n // Load highlight.js on mount\n createEffect(async () => {\n if (!hljs) {\n try {\n // Use the full highlight.js bundle with all languages for simplicity\n const module = await import('highlight.js')\n const resolved = module.default || module\n // Guard: verify the resolved module has the expected API\n if (typeof resolved?.highlight === 'function') {\n hljs = resolved\n } else {\n console.warn('highlight.js loaded but missing highlight() method')\n }\n setIsHljsLoaded(true)\n } catch (e) {\n console.warn('Failed to load highlight.js', e)\n // Continue without highlighting - fallback to plain text\n setIsHljsLoaded(true)\n }\n } else {\n setIsHljsLoaded(true)\n }\n })\n\n // Theme management - Sprint Ultimate U.1: Reactive theme synchronization\n // Load both theme stylesheets once, then toggle via data-attribute\n createEffect(async () => {\n if (isServer || stylesLoaded) return\n\n // Load both themes upfront for instant switching\n try {\n await Promise.all([\n import('highlight.js/styles/github.css'),\n import('highlight.js/styles/github-dark.css')\n ])\n stylesLoaded = true\n } catch (e) {\n console.warn('Failed to load highlight.js themes', e)\n }\n })\n\n // Reactive theme detection - listens to system preference changes\n createEffect(() => {\n if (isServer) return\n\n // Priority 1: Explicit theme from params\n const paramTheme = params()?.theme\n if (paramTheme) {\n setActiveTheme(paramTheme)\n return\n }\n\n // Priority 2: System preference with live updates\n // Check if matchMedia is available (not in all test environments)\n if (typeof window !== 'undefined' && typeof window.matchMedia === 'function') {\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')\n setActiveTheme(mediaQuery.matches ? 'dark' : 'light')\n\n const handleChange = (e: MediaQueryListEvent) => {\n // Only update if no explicit theme in params\n if (!params()?.theme) {\n setActiveTheme(e.matches ? 'dark' : 'light')\n }\n }\n\n mediaQuery.addEventListener('change', handleChange)\n onCleanup(() => mediaQuery.removeEventListener('change', handleChange))\n }\n })\n\n // Apply highlighting\n createEffect(() => {\n const code = params()?.code || ''\n const language = params()?.language || ''\n\n if (hljs && isHljsLoaded()) {\n try {\n let result\n if (language && hljs.getLanguage(language)) {\n result = hljs.highlight(code, { language }).value\n } else {\n result = hljs.highlightAuto(code).value\n }\n setHighlightedCode(result)\n } catch (e) {\n setHighlightedCode(escapeHtml(code))\n }\n } else {\n // Fallback: no highlight.js → the raw source goes straight to an\n // `innerHTML` sink, so it must be fully escaped. The previous\n // hand-rolled `< >`-only replace left `&` unescaped, which made\n // code containing `<script>` render as a literal tag.\n setHighlightedCode(escapeHtml(code))\n }\n })\n\n // Line numbers generation\n const lineNumbers = () => {\n if (params()?.showLineNumbers === false) return []\n const code = params()?.code || ''\n const lines = code.split('\\n')\n const start = params()?.startLine || 1\n return lines.map((_, i) => start + i)\n }\n\n const handleCopy = async () => {\n const code = params()?.code\n if (code) {\n try {\n await navigator.clipboard.writeText(code)\n setIsCopied(true)\n setTimeout(() => setIsCopied(false), 2000)\n } catch (e) {\n console.error('Failed to copy code', e)\n }\n }\n }\n\n return (\n <ExpandableWrapper title={params()?.filename || params()?.language || strings.codeTitle} copyData={params()?.code} copyLabel={strings.codeCopy} toolbarVariant={props.toolbarVariant}>\n <div class={`w-full bg-gray-50 dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden text-sm flex flex-col ${isExpanded() ? 'flex-1 min-h-0' : ''}`}>\n {/* Header */}\n <div class=\"flex items-center justify-between px-4 py-2 bg-gray-100 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 shrink-0\">\n <div class=\"font-mono text-xs text-gray-600 dark:text-gray-400\">\n {params()?.filename || params()?.language || strings.codeTitle}\n </div>\n <div class=\"flex items-center gap-2\">\n {/* Search input (v6.2.0) */}\n <input\n type=\"text\"\n value={searchQuery()}\n onInput={(e) => setSearchQuery(e.currentTarget.value)}\n placeholder={strings.codeSearchPlaceholder}\n class=\"px-2 py-0.5 text-xs border border-gray-200 dark:border-gray-600 rounded bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-400 focus:border-blue-400 focus:ring-1 focus:ring-blue-400 outline-none w-32\"\n aria-label={strings.codeSearchAria}\n />\n {/* Download button (v6.2.0) */}\n <button\n onClick={handleDownload}\n class=\"text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 focus:outline-none transition-colors\"\n aria-label={strings.codeDownloadAria}\n title={strings.codeDownload}\n >\n <svg class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\" />\n </svg>\n </button>\n {/* Word wrap toggle */}\n <button\n onClick={() => setWordWrap(!wordWrap())}\n class={`focus:outline-none transition-colors ${wordWrap() ? 'text-blue-500 dark:text-blue-400' : 'text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200'}`}\n aria-label={strings.codeToggleWordWrap}\n title={wordWrap() ? strings.codeWordWrapDisable : strings.codeWordWrapEnable}\n >\n <svg class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M3 10h10a4 4 0 010 8H9m4 0l-3-3m3 3l-3 3M3 6h18M3 14h4\" />\n </svg>\n </button>\n {/* Copy button */}\n <button\n onClick={handleCopy}\n class=\"text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 focus:outline-none transition-colors\"\n aria-label={strings.codeCopy}\n title={strings.codeCopy}\n >\n <Show when={isCopied()} fallback={\n <svg class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\" />\n </svg>\n }>\n <svg class=\"w-4 h-4 text-green-500\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13l4 4L19 7\" />\n </svg>\n </Show>\n </button>\n </div>\n </div>\n\n {/* Code Area */}\n <div\n class={`relative overflow-auto flex ${isExpanded() ? 'flex-1 min-h-0' : ''}`}\n style={!isExpanded() && params()?.maxHeight ? { 'max-height': params()?.maxHeight } : {}}\n >\n {/* Line Numbers */}\n <Show when={params()?.showLineNumbers !== false}>\n <div class=\"flex-none text-right select-none bg-gray-100 dark:bg-gray-800 border-r border-gray-200 dark:border-gray-700 py-4 px-2 text-gray-400 font-mono text-xs leading-5\">\n <For each={lineNumbers()}>\n {(num) => <div class=\"px-2\">{num}</div>}\n </For>\n </div>\n </Show>\n\n {/* Code Content - Sprint Ultimate U.1: data-theme for reactive theming */}\n <pre\n class=\"flex-1 m-0 p-4 font-mono text-gray-800 dark:text-gray-100 bg-transparent leading-5\"\n style={wordWrap() ? { 'white-space': 'pre-wrap', 'word-break': 'break-all' } : {}}\n data-theme={activeTheme()}\n >\n <code\n class={`hljs ${params()?.language ? `language-${params()?.language}` : ''}`}\n innerHTML={displayedHTML()}\n />\n </pre>\n </div>\n </div>\n </ExpandableWrapper>\n )\n}\n"],"names":["LANGUAGE_EXTENSIONS","typescript","tsx","javascript","jsx","python","ruby","go","rust","java","kotlin","swift","php","csharp","cpp","c","sql","json","yaml","toml","bash","shell","html","css","scss","markdown","xml","graphql","hljs","stylesLoaded","CodeBlockRenderer","props","strings","useMCPUIStrings","highlightedCode","setHighlightedCode","createSignal","isCopied","setIsCopied","isHljsLoaded","setIsHljsLoaded","activeTheme","setActiveTheme","wordWrap","setWordWrap","params","component","isExpanded","useExpanded","searchQuery","setSearchQuery","displayedHTML","q","trim","highlightQuery","handleDownload","code","lang","language","toLowerCase","ext","stem","filename","Date","now","replace","endsWith","blob","Blob","type","url","URL","createObjectURL","a","document","createElement","href","download","body","appendChild","click","removeChild","revokeObjectURL","createEffect","module","resolved","default","highlight","console","warn","e","isServer","Promise","all","paramTheme","theme","window","matchMedia","mediaQuery","matches","handleChange","addEventListener","onCleanup","removeEventListener","result","getLanguage","value","highlightAuto","escapeHtml","lineNumbers","showLineNumbers","lines","split","start","startLine","map","_","i","handleCopy","navigator","clipboard","writeText","setTimeout","error","_$createComponent","ExpandableWrapper","title","codeTitle","copyData","copyLabel","codeCopy","toolbarVariant","children","_el$","_$getNextElement","_tmpl$3","_el$2","firstChild","_el$3","_el$4","nextSibling","_el$5","_el$6","_el$7","_el$8","_el$0","_el$12","_el$13","_co$","_$getNextMarker","_el$10","_el$11","_$insert","$$input","currentTarget","$$click","Show","when","fallback","_tmpl$4","_tmpl$","_el$1","_tmpl$2","For","each","num","_el$15","_tmpl$5","_$effect","_p$","_v$","_v$2","codeSearchPlaceholder","_v$3","codeSearchAria","_v$4","codeDownloadAria","_v$5","codeDownload","_v$6","_v$7","codeToggleWordWrap","_v$8","codeWordWrapDisable","codeWordWrapEnable","_v$9","_v$0","_v$1","_v$10","maxHeight","_v$11","_v$12","_v$13","_v$14","_$className","t","_$setAttribute","o","n","s","h","r","d","l","u","_$style","w","m","f","_$setProperty","undefined","_$runHydrationEvents","_$delegateEvents"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeBlockRenderer.d.ts","sourceRoot":"","sources":["../../src/components/CodeBlockRenderer.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAoD,MAAM,UAAU,CAAA;AAEtF,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"CodeBlockRenderer.d.ts","sourceRoot":"","sources":["../../src/components/CodeBlockRenderer.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAoD,MAAM,UAAU,CAAA;AAEtF,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAqBhE,MAAM,WAAW,sBAAsB;IACnC;;OAEG;IACH,SAAS,CAAC,EAAE,WAAW,CAAA;IAEvB;;OAEG;IACH,MAAM,CAAC,EAAE,mBAAmB,CAAA;IAE5B;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAAA;CAC9C;AAED,eAAO,MAAM,iBAAiB,EAAE,SAAS,CAAC,sBAAsB,CAsP/D,CAAA"}
|
|
@@ -3,7 +3,8 @@ import { createSignal, createEffect, onCleanup, Show, For } from "solid-js";
|
|
|
3
3
|
import { useExpanded, ExpandableWrapper } from "./ExpandableWrapper.js";
|
|
4
4
|
import { highlightQuery } from "./UIResourceRenderer.js";
|
|
5
5
|
import { escapeHtml } from "../utils/escape-html.js";
|
|
6
|
-
|
|
6
|
+
import { useMCPUIStrings } from "../context/MCPUIStringsContext.js";
|
|
7
|
+
var _tmpl$ = /* @__PURE__ */ template(`<svg class="w-4 h-4 text-green-500"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M5 13l4 4L19 7">`), _tmpl$2 = /* @__PURE__ */ template(`<div class="flex-none text-right select-none bg-gray-100 dark:bg-gray-800 border-r border-gray-200 dark:border-gray-700 py-4 px-2 text-gray-400 font-mono text-xs leading-5">`), _tmpl$3 = /* @__PURE__ */ template(`<div><div class="flex items-center justify-between px-4 py-2 bg-gray-100 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 shrink-0"><div class="font-mono text-xs text-gray-600 dark:text-gray-400"></div><div class="flex items-center gap-2"><input type=text class="px-2 py-0.5 text-xs border border-gray-200 dark:border-gray-600 rounded bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-400 focus:border-blue-400 focus:ring-1 focus:ring-blue-400 outline-none w-32"><button class="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 focus:outline-none transition-colors"><svg class="w-4 h-4"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path></svg></button><button><svg class="w-4 h-4"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M3 10h10a4 4 0 010 8H9m4 0l-3-3m3 3l-3 3M3 6h18M3 14h4"></path></svg></button><button class="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 focus:outline-none transition-colors"></button></div></div><div><!$><!/><pre class="flex-1 m-0 p-4 font-mono text-gray-800 dark:text-gray-100 bg-transparent leading-5"><code>`), _tmpl$4 = /* @__PURE__ */ template(`<svg class="w-4 h-4"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z">`), _tmpl$5 = /* @__PURE__ */ template(`<div class=px-2>`);
|
|
7
8
|
const LANGUAGE_EXTENSIONS = {
|
|
8
9
|
typescript: "ts",
|
|
9
10
|
tsx: "tsx",
|
|
@@ -36,6 +37,7 @@ const LANGUAGE_EXTENSIONS = {
|
|
|
36
37
|
let hljs = null;
|
|
37
38
|
let stylesLoaded = false;
|
|
38
39
|
const CodeBlockRenderer = (props) => {
|
|
40
|
+
const strings = useMCPUIStrings();
|
|
39
41
|
const [highlightedCode, setHighlightedCode] = createSignal("");
|
|
40
42
|
const [isCopied, setIsCopied] = createSignal(false);
|
|
41
43
|
const [isHljsLoaded, setIsHljsLoaded] = createSignal(false);
|
|
@@ -166,13 +168,15 @@ const CodeBlockRenderer = (props) => {
|
|
|
166
168
|
return createComponent(ExpandableWrapper, {
|
|
167
169
|
get title() {
|
|
168
170
|
var _a, _b;
|
|
169
|
-
return ((_a = params()) == null ? void 0 : _a.filename) || ((_b = params()) == null ? void 0 : _b.language) ||
|
|
171
|
+
return ((_a = params()) == null ? void 0 : _a.filename) || ((_b = params()) == null ? void 0 : _b.language) || strings.codeTitle;
|
|
170
172
|
},
|
|
171
173
|
get copyData() {
|
|
172
174
|
var _a;
|
|
173
175
|
return (_a = params()) == null ? void 0 : _a.code;
|
|
174
176
|
},
|
|
175
|
-
copyLabel
|
|
177
|
+
get copyLabel() {
|
|
178
|
+
return strings.codeCopy;
|
|
179
|
+
},
|
|
176
180
|
get toolbarVariant() {
|
|
177
181
|
return props.toolbarVariant;
|
|
178
182
|
},
|
|
@@ -180,7 +184,7 @@ const CodeBlockRenderer = (props) => {
|
|
|
180
184
|
var _el$ = getNextElement(_tmpl$3), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.nextSibling, _el$5 = _el$4.firstChild, _el$6 = _el$5.nextSibling, _el$7 = _el$6.nextSibling, _el$8 = _el$7.nextSibling, _el$0 = _el$2.nextSibling, _el$12 = _el$0.firstChild, [_el$13, _co$] = getNextMarker(_el$12.nextSibling), _el$10 = _el$13.nextSibling, _el$11 = _el$10.firstChild;
|
|
181
185
|
insert(_el$3, () => {
|
|
182
186
|
var _a, _b;
|
|
183
|
-
return ((_a = params()) == null ? void 0 : _a.filename) || ((_b = params()) == null ? void 0 : _b.language) ||
|
|
187
|
+
return ((_a = params()) == null ? void 0 : _a.filename) || ((_b = params()) == null ? void 0 : _b.language) || strings.codeTitle;
|
|
184
188
|
});
|
|
185
189
|
_el$5.$$input = (e) => setSearchQuery(e.currentTarget.value);
|
|
186
190
|
_el$6.$$click = handleDownload;
|
|
@@ -219,21 +223,28 @@ const CodeBlockRenderer = (props) => {
|
|
|
219
223
|
}), _el$13, _co$);
|
|
220
224
|
effect((_p$) => {
|
|
221
225
|
var _a, _b, _c, _d;
|
|
222
|
-
var _v$ = `w-full bg-gray-50 dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden text-sm flex flex-col ${isExpanded() ? "flex-1 min-h-0" : ""}`, _v$2 = `focus:outline-none transition-colors ${wordWrap() ? "text-blue-500 dark:text-blue-400" : "text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"}`, _v$
|
|
226
|
+
var _v$ = `w-full bg-gray-50 dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden text-sm flex flex-col ${isExpanded() ? "flex-1 min-h-0" : ""}`, _v$2 = strings.codeSearchPlaceholder, _v$3 = strings.codeSearchAria, _v$4 = strings.codeDownloadAria, _v$5 = strings.codeDownload, _v$6 = `focus:outline-none transition-colors ${wordWrap() ? "text-blue-500 dark:text-blue-400" : "text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"}`, _v$7 = strings.codeToggleWordWrap, _v$8 = wordWrap() ? strings.codeWordWrapDisable : strings.codeWordWrapEnable, _v$9 = strings.codeCopy, _v$0 = strings.codeCopy, _v$1 = `relative overflow-auto flex ${isExpanded() ? "flex-1 min-h-0" : ""}`, _v$10 = !isExpanded() && ((_a = params()) == null ? void 0 : _a.maxHeight) ? {
|
|
223
227
|
"max-height": (_b = params()) == null ? void 0 : _b.maxHeight
|
|
224
|
-
} : {}, _v$
|
|
228
|
+
} : {}, _v$11 = wordWrap() ? {
|
|
225
229
|
"white-space": "pre-wrap",
|
|
226
230
|
"word-break": "break-all"
|
|
227
|
-
} : {}, _v$
|
|
231
|
+
} : {}, _v$12 = activeTheme(), _v$13 = `hljs ${((_c = params()) == null ? void 0 : _c.language) ? `language-${(_d = params()) == null ? void 0 : _d.language}` : ""}`, _v$14 = displayedHTML();
|
|
228
232
|
_v$ !== _p$.e && className(_el$, _p$.e = _v$);
|
|
229
|
-
_v$2 !== _p$.t &&
|
|
230
|
-
_v$3 !== _p$.a && setAttribute(_el$
|
|
231
|
-
_v$4 !== _p$.o &&
|
|
232
|
-
_p$.i
|
|
233
|
-
_p$.n
|
|
234
|
-
_v$7 !== _p$.s && setAttribute(_el$
|
|
235
|
-
_v$8 !== _p$.h &&
|
|
236
|
-
_v$9 !== _p$.r &&
|
|
233
|
+
_v$2 !== _p$.t && setAttribute(_el$5, "placeholder", _p$.t = _v$2);
|
|
234
|
+
_v$3 !== _p$.a && setAttribute(_el$5, "aria-label", _p$.a = _v$3);
|
|
235
|
+
_v$4 !== _p$.o && setAttribute(_el$6, "aria-label", _p$.o = _v$4);
|
|
236
|
+
_v$5 !== _p$.i && setAttribute(_el$6, "title", _p$.i = _v$5);
|
|
237
|
+
_v$6 !== _p$.n && className(_el$7, _p$.n = _v$6);
|
|
238
|
+
_v$7 !== _p$.s && setAttribute(_el$7, "aria-label", _p$.s = _v$7);
|
|
239
|
+
_v$8 !== _p$.h && setAttribute(_el$7, "title", _p$.h = _v$8);
|
|
240
|
+
_v$9 !== _p$.r && setAttribute(_el$8, "aria-label", _p$.r = _v$9);
|
|
241
|
+
_v$0 !== _p$.d && setAttribute(_el$8, "title", _p$.d = _v$0);
|
|
242
|
+
_v$1 !== _p$.l && className(_el$0, _p$.l = _v$1);
|
|
243
|
+
_p$.u = style(_el$0, _v$10, _p$.u);
|
|
244
|
+
_p$.c = style(_el$10, _v$11, _p$.c);
|
|
245
|
+
_v$12 !== _p$.w && setAttribute(_el$10, "data-theme", _p$.w = _v$12);
|
|
246
|
+
_v$13 !== _p$.m && className(_el$11, _p$.m = _v$13);
|
|
247
|
+
_v$14 !== _p$.f && setProperty(_el$11, "innerHTML", _p$.f = _v$14);
|
|
237
248
|
return _p$;
|
|
238
249
|
}, {
|
|
239
250
|
e: void 0,
|
|
@@ -244,7 +255,14 @@ const CodeBlockRenderer = (props) => {
|
|
|
244
255
|
n: void 0,
|
|
245
256
|
s: void 0,
|
|
246
257
|
h: void 0,
|
|
247
|
-
r: void 0
|
|
258
|
+
r: void 0,
|
|
259
|
+
d: void 0,
|
|
260
|
+
l: void 0,
|
|
261
|
+
u: void 0,
|
|
262
|
+
c: void 0,
|
|
263
|
+
w: void 0,
|
|
264
|
+
m: void 0,
|
|
265
|
+
f: void 0
|
|
248
266
|
});
|
|
249
267
|
effect(() => setProperty(_el$5, "value", searchQuery()));
|
|
250
268
|
runHydrationEvents();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeBlockRenderer.js","sources":["../../src/components/CodeBlockRenderer.tsx"],"sourcesContent":["/**\n * CodeBlockRenderer - Syntax highlighted code block\n * Sprint 6: Code & Maps\n * Sprint Ultimate: Theme Synchronization (U.1)\n */\n\nimport { Component, createEffect, onCleanup, createSignal, Show, For } from 'solid-js'\nimport { isServer } from 'solid-js/web'\nimport type { UIComponent, CodeComponentParams } from '../types'\nimport { ExpandableWrapper, useExpanded } from './ExpandableWrapper'\nimport { highlightQuery } from './UIResourceRenderer'\nimport { escapeHtml } from '../utils/escape-html'\n\n/** Map of `params.language` → file extension for the v6.2.0 download button. */\nconst LANGUAGE_EXTENSIONS: Record<string, string> = {\n typescript: 'ts', tsx: 'tsx', javascript: 'js', jsx: 'jsx',\n python: 'py', ruby: 'rb', go: 'go', rust: 'rs', java: 'java',\n kotlin: 'kt', swift: 'swift', php: 'php', csharp: 'cs', cpp: 'cpp',\n c: 'c', sql: 'sql', json: 'json', yaml: 'yml', toml: 'toml',\n bash: 'sh', shell: 'sh', html: 'html', css: 'css', scss: 'scss',\n markdown: 'md', xml: 'xml', graphql: 'graphql',\n}\n\n// Lazy load highlight.js\nlet hljs: any = null\n// Track if styles have been loaded globally\nlet stylesLoaded = false\n\nexport interface CodeBlockRendererProps {\n /**\n * UIComponent containing code params\n */\n component?: UIComponent\n\n /**\n * Direct code params\n */\n params?: CodeComponentParams\n\n /**\n * Forwarded to the underlying `<ExpandableWrapper>` (v6.3.1).\n * @see ExpandableWrapperProps.toolbarVariant\n */\n toolbarVariant?: 'hover' | 'always-visible'\n}\n\nexport const CodeBlockRenderer: Component<CodeBlockRendererProps> = (props) => {\n const [highlightedCode, setHighlightedCode] = createSignal<string>('')\n const [isCopied, setIsCopied] = createSignal(false)\n const [isHljsLoaded, setIsHljsLoaded] = createSignal(false)\n const [activeTheme, setActiveTheme] = createSignal<'light' | 'dark'>('dark')\n const [wordWrap, setWordWrap] = createSignal(false)\n\n const params = () => props.params || (props.component?.params as CodeComponentParams)\n const isExpanded = useExpanded()\n const [searchQuery, setSearchQuery] = createSignal('')\n\n // v6.2.0 — search highlight: re-wraps `<mark>` around matches in the\n // already-highlighted (hljs) HTML output. `highlightQuery` is the same\n // helper TableRenderer uses (only wraps text outside of HTML tags so\n // syntax span colors stay intact).\n const displayedHTML = () => {\n const q = searchQuery().trim()\n return q ? highlightQuery(highlightedCode(), q) : highlightedCode()\n }\n\n const handleDownload = () => {\n const code = params()?.code\n if (!code) return\n const lang = (params()?.language || '').toLowerCase()\n const ext = LANGUAGE_EXTENSIONS[lang] || 'txt'\n const stem = (params()?.filename || `code-${Date.now()}`).replace(/\\.[^.]+$/, '')\n const filename = stem.endsWith(`.${ext}`) ? stem : `${stem}.${ext}`\n const blob = new Blob([code], { type: 'text/plain' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = filename\n document.body.appendChild(a)\n a.click()\n document.body.removeChild(a)\n URL.revokeObjectURL(url)\n }\n\n // Load highlight.js on mount\n createEffect(async () => {\n if (!hljs) {\n try {\n // Use the full highlight.js bundle with all languages for simplicity\n const module = await import('highlight.js')\n const resolved = module.default || module\n // Guard: verify the resolved module has the expected API\n if (typeof resolved?.highlight === 'function') {\n hljs = resolved\n } else {\n console.warn('highlight.js loaded but missing highlight() method')\n }\n setIsHljsLoaded(true)\n } catch (e) {\n console.warn('Failed to load highlight.js', e)\n // Continue without highlighting - fallback to plain text\n setIsHljsLoaded(true)\n }\n } else {\n setIsHljsLoaded(true)\n }\n })\n\n // Theme management - Sprint Ultimate U.1: Reactive theme synchronization\n // Load both theme stylesheets once, then toggle via data-attribute\n createEffect(async () => {\n if (isServer || stylesLoaded) return\n\n // Load both themes upfront for instant switching\n try {\n await Promise.all([\n import('highlight.js/styles/github.css'),\n import('highlight.js/styles/github-dark.css')\n ])\n stylesLoaded = true\n } catch (e) {\n console.warn('Failed to load highlight.js themes', e)\n }\n })\n\n // Reactive theme detection - listens to system preference changes\n createEffect(() => {\n if (isServer) return\n\n // Priority 1: Explicit theme from params\n const paramTheme = params()?.theme\n if (paramTheme) {\n setActiveTheme(paramTheme)\n return\n }\n\n // Priority 2: System preference with live updates\n // Check if matchMedia is available (not in all test environments)\n if (typeof window !== 'undefined' && typeof window.matchMedia === 'function') {\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')\n setActiveTheme(mediaQuery.matches ? 'dark' : 'light')\n\n const handleChange = (e: MediaQueryListEvent) => {\n // Only update if no explicit theme in params\n if (!params()?.theme) {\n setActiveTheme(e.matches ? 'dark' : 'light')\n }\n }\n\n mediaQuery.addEventListener('change', handleChange)\n onCleanup(() => mediaQuery.removeEventListener('change', handleChange))\n }\n })\n\n // Apply highlighting\n createEffect(() => {\n const code = params()?.code || ''\n const language = params()?.language || ''\n\n if (hljs && isHljsLoaded()) {\n try {\n let result\n if (language && hljs.getLanguage(language)) {\n result = hljs.highlight(code, { language }).value\n } else {\n result = hljs.highlightAuto(code).value\n }\n setHighlightedCode(result)\n } catch (e) {\n setHighlightedCode(escapeHtml(code))\n }\n } else {\n // Fallback: no highlight.js → the raw source goes straight to an\n // `innerHTML` sink, so it must be fully escaped. The previous\n // hand-rolled `< >`-only replace left `&` unescaped, which made\n // code containing `<script>` render as a literal tag.\n setHighlightedCode(escapeHtml(code))\n }\n })\n\n // Line numbers generation\n const lineNumbers = () => {\n if (params()?.showLineNumbers === false) return []\n const code = params()?.code || ''\n const lines = code.split('\\n')\n const start = params()?.startLine || 1\n return lines.map((_, i) => start + i)\n }\n\n const handleCopy = async () => {\n const code = params()?.code\n if (code) {\n try {\n await navigator.clipboard.writeText(code)\n setIsCopied(true)\n setTimeout(() => setIsCopied(false), 2000)\n } catch (e) {\n console.error('Failed to copy code', e)\n }\n }\n }\n\n return (\n <ExpandableWrapper title={params()?.filename || params()?.language || 'Code'} copyData={params()?.code} copyLabel=\"Copy code\" toolbarVariant={props.toolbarVariant}>\n <div class={`w-full bg-gray-50 dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden text-sm flex flex-col ${isExpanded() ? 'flex-1 min-h-0' : ''}`}>\n {/* Header */}\n <div class=\"flex items-center justify-between px-4 py-2 bg-gray-100 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 shrink-0\">\n <div class=\"font-mono text-xs text-gray-600 dark:text-gray-400\">\n {params()?.filename || params()?.language || 'Code'}\n </div>\n <div class=\"flex items-center gap-2\">\n {/* Search input (v6.2.0) */}\n <input\n type=\"text\"\n value={searchQuery()}\n onInput={(e) => setSearchQuery(e.currentTarget.value)}\n placeholder=\"Search…\"\n class=\"px-2 py-0.5 text-xs border border-gray-200 dark:border-gray-600 rounded bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-400 focus:border-blue-400 focus:ring-1 focus:ring-blue-400 outline-none w-32\"\n aria-label=\"Search in code\"\n />\n {/* Download button (v6.2.0) */}\n <button\n onClick={handleDownload}\n class=\"text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 focus:outline-none transition-colors\"\n aria-label=\"Download code as file\"\n title=\"Download code\"\n >\n <svg class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\" />\n </svg>\n </button>\n {/* Word wrap toggle */}\n <button\n onClick={() => setWordWrap(!wordWrap())}\n class={`focus:outline-none transition-colors ${wordWrap() ? 'text-blue-500 dark:text-blue-400' : 'text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200'}`}\n aria-label=\"Toggle word wrap\"\n title={wordWrap() ? 'Disable word wrap' : 'Enable word wrap'}\n >\n <svg class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M3 10h10a4 4 0 010 8H9m4 0l-3-3m3 3l-3 3M3 6h18M3 14h4\" />\n </svg>\n </button>\n {/* Copy button */}\n <button\n onClick={handleCopy}\n class=\"text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 focus:outline-none transition-colors\"\n aria-label=\"Copy code\"\n title=\"Copy code\"\n >\n <Show when={isCopied()} fallback={\n <svg class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\" />\n </svg>\n }>\n <svg class=\"w-4 h-4 text-green-500\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13l4 4L19 7\" />\n </svg>\n </Show>\n </button>\n </div>\n </div>\n\n {/* Code Area */}\n <div\n class={`relative overflow-auto flex ${isExpanded() ? 'flex-1 min-h-0' : ''}`}\n style={!isExpanded() && params()?.maxHeight ? { 'max-height': params()?.maxHeight } : {}}\n >\n {/* Line Numbers */}\n <Show when={params()?.showLineNumbers !== false}>\n <div class=\"flex-none text-right select-none bg-gray-100 dark:bg-gray-800 border-r border-gray-200 dark:border-gray-700 py-4 px-2 text-gray-400 font-mono text-xs leading-5\">\n <For each={lineNumbers()}>\n {(num) => <div class=\"px-2\">{num}</div>}\n </For>\n </div>\n </Show>\n\n {/* Code Content - Sprint Ultimate U.1: data-theme for reactive theming */}\n <pre\n class=\"flex-1 m-0 p-4 font-mono text-gray-800 dark:text-gray-100 bg-transparent leading-5\"\n style={wordWrap() ? { 'white-space': 'pre-wrap', 'word-break': 'break-all' } : {}}\n data-theme={activeTheme()}\n >\n <code\n class={`hljs ${params()?.language ? `language-${params()?.language}` : ''}`}\n innerHTML={displayedHTML()}\n />\n </pre>\n </div>\n </div>\n </ExpandableWrapper>\n )\n}\n"],"names":["LANGUAGE_EXTENSIONS","typescript","tsx","javascript","jsx","python","ruby","go","rust","java","kotlin","swift","php","csharp","cpp","c","sql","json","yaml","toml","bash","shell","html","css","scss","markdown","xml","graphql","hljs","stylesLoaded","CodeBlockRenderer","props","highlightedCode","setHighlightedCode","createSignal","isCopied","setIsCopied","isHljsLoaded","setIsHljsLoaded","activeTheme","setActiveTheme","wordWrap","setWordWrap","params","component","isExpanded","useExpanded","searchQuery","setSearchQuery","displayedHTML","q","trim","highlightQuery","handleDownload","code","lang","language","toLowerCase","ext","stem","filename","Date","now","replace","endsWith","blob","Blob","type","url","URL","createObjectURL","a","document","createElement","href","download","body","appendChild","click","removeChild","revokeObjectURL","createEffect","module","resolved","default","highlight","console","warn","e","isServer","Promise","all","paramTheme","theme","window","matchMedia","mediaQuery","matches","handleChange","addEventListener","onCleanup","removeEventListener","result","getLanguage","value","highlightAuto","escapeHtml","lineNumbers","showLineNumbers","lines","split","start","startLine","map","_","i","handleCopy","navigator","clipboard","writeText","setTimeout","error","_$createComponent","ExpandableWrapper","title","copyData","copyLabel","toolbarVariant","children","_el$","_$getNextElement","_tmpl$3","_el$2","firstChild","_el$3","_el$4","nextSibling","_el$5","_el$6","_el$7","_el$8","_el$0","_el$12","_el$13","_co$","_$getNextMarker","_el$10","_el$11","_$insert","$$input","currentTarget","$$click","Show","when","fallback","_tmpl$4","_tmpl$","_el$1","_tmpl$2","For","each","num","_el$15","_tmpl$5","_$effect","_p$","_v$","_v$2","_v$3","_v$4","_v$5","maxHeight","_v$6","_v$7","_v$8","_v$9","_$className","t","_$setAttribute","o","_$style","n","s","h","r","_$setProperty","undefined","_$runHydrationEvents","_$delegateEvents"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CodeBlockRenderer.js","sources":["../../src/components/CodeBlockRenderer.tsx"],"sourcesContent":["/**\n * CodeBlockRenderer - Syntax highlighted code block\n * Sprint 6: Code & Maps\n * Sprint Ultimate: Theme Synchronization (U.1)\n */\n\nimport { Component, createEffect, onCleanup, createSignal, Show, For } from 'solid-js'\nimport { isServer } from 'solid-js/web'\nimport type { UIComponent, CodeComponentParams } from '../types'\nimport { ExpandableWrapper, useExpanded } from './ExpandableWrapper'\nimport { highlightQuery } from './UIResourceRenderer'\nimport { escapeHtml } from '../utils/escape-html'\nimport { useMCPUIStrings } from '../context/MCPUIStringsContext'\n\n/** Map of `params.language` → file extension for the v6.2.0 download button. */\nconst LANGUAGE_EXTENSIONS: Record<string, string> = {\n typescript: 'ts', tsx: 'tsx', javascript: 'js', jsx: 'jsx',\n python: 'py', ruby: 'rb', go: 'go', rust: 'rs', java: 'java',\n kotlin: 'kt', swift: 'swift', php: 'php', csharp: 'cs', cpp: 'cpp',\n c: 'c', sql: 'sql', json: 'json', yaml: 'yml', toml: 'toml',\n bash: 'sh', shell: 'sh', html: 'html', css: 'css', scss: 'scss',\n markdown: 'md', xml: 'xml', graphql: 'graphql',\n}\n\n// Lazy load highlight.js\nlet hljs: any = null\n// Track if styles have been loaded globally\nlet stylesLoaded = false\n\nexport interface CodeBlockRendererProps {\n /**\n * UIComponent containing code params\n */\n component?: UIComponent\n\n /**\n * Direct code params\n */\n params?: CodeComponentParams\n\n /**\n * Forwarded to the underlying `<ExpandableWrapper>` (v6.3.1).\n * @see ExpandableWrapperProps.toolbarVariant\n */\n toolbarVariant?: 'hover' | 'always-visible'\n}\n\nexport const CodeBlockRenderer: Component<CodeBlockRendererProps> = (props) => {\n const strings = useMCPUIStrings()\n const [highlightedCode, setHighlightedCode] = createSignal<string>('')\n const [isCopied, setIsCopied] = createSignal(false)\n const [isHljsLoaded, setIsHljsLoaded] = createSignal(false)\n const [activeTheme, setActiveTheme] = createSignal<'light' | 'dark'>('dark')\n const [wordWrap, setWordWrap] = createSignal(false)\n\n const params = () => props.params || (props.component?.params as CodeComponentParams)\n const isExpanded = useExpanded()\n const [searchQuery, setSearchQuery] = createSignal('')\n\n // v6.2.0 — search highlight: re-wraps `<mark>` around matches in the\n // already-highlighted (hljs) HTML output. `highlightQuery` is the same\n // helper TableRenderer uses (only wraps text outside of HTML tags so\n // syntax span colors stay intact).\n const displayedHTML = () => {\n const q = searchQuery().trim()\n return q ? highlightQuery(highlightedCode(), q) : highlightedCode()\n }\n\n const handleDownload = () => {\n const code = params()?.code\n if (!code) return\n const lang = (params()?.language || '').toLowerCase()\n const ext = LANGUAGE_EXTENSIONS[lang] || 'txt'\n const stem = (params()?.filename || `code-${Date.now()}`).replace(/\\.[^.]+$/, '')\n const filename = stem.endsWith(`.${ext}`) ? stem : `${stem}.${ext}`\n const blob = new Blob([code], { type: 'text/plain' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = filename\n document.body.appendChild(a)\n a.click()\n document.body.removeChild(a)\n URL.revokeObjectURL(url)\n }\n\n // Load highlight.js on mount\n createEffect(async () => {\n if (!hljs) {\n try {\n // Use the full highlight.js bundle with all languages for simplicity\n const module = await import('highlight.js')\n const resolved = module.default || module\n // Guard: verify the resolved module has the expected API\n if (typeof resolved?.highlight === 'function') {\n hljs = resolved\n } else {\n console.warn('highlight.js loaded but missing highlight() method')\n }\n setIsHljsLoaded(true)\n } catch (e) {\n console.warn('Failed to load highlight.js', e)\n // Continue without highlighting - fallback to plain text\n setIsHljsLoaded(true)\n }\n } else {\n setIsHljsLoaded(true)\n }\n })\n\n // Theme management - Sprint Ultimate U.1: Reactive theme synchronization\n // Load both theme stylesheets once, then toggle via data-attribute\n createEffect(async () => {\n if (isServer || stylesLoaded) return\n\n // Load both themes upfront for instant switching\n try {\n await Promise.all([\n import('highlight.js/styles/github.css'),\n import('highlight.js/styles/github-dark.css')\n ])\n stylesLoaded = true\n } catch (e) {\n console.warn('Failed to load highlight.js themes', e)\n }\n })\n\n // Reactive theme detection - listens to system preference changes\n createEffect(() => {\n if (isServer) return\n\n // Priority 1: Explicit theme from params\n const paramTheme = params()?.theme\n if (paramTheme) {\n setActiveTheme(paramTheme)\n return\n }\n\n // Priority 2: System preference with live updates\n // Check if matchMedia is available (not in all test environments)\n if (typeof window !== 'undefined' && typeof window.matchMedia === 'function') {\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')\n setActiveTheme(mediaQuery.matches ? 'dark' : 'light')\n\n const handleChange = (e: MediaQueryListEvent) => {\n // Only update if no explicit theme in params\n if (!params()?.theme) {\n setActiveTheme(e.matches ? 'dark' : 'light')\n }\n }\n\n mediaQuery.addEventListener('change', handleChange)\n onCleanup(() => mediaQuery.removeEventListener('change', handleChange))\n }\n })\n\n // Apply highlighting\n createEffect(() => {\n const code = params()?.code || ''\n const language = params()?.language || ''\n\n if (hljs && isHljsLoaded()) {\n try {\n let result\n if (language && hljs.getLanguage(language)) {\n result = hljs.highlight(code, { language }).value\n } else {\n result = hljs.highlightAuto(code).value\n }\n setHighlightedCode(result)\n } catch (e) {\n setHighlightedCode(escapeHtml(code))\n }\n } else {\n // Fallback: no highlight.js → the raw source goes straight to an\n // `innerHTML` sink, so it must be fully escaped. The previous\n // hand-rolled `< >`-only replace left `&` unescaped, which made\n // code containing `<script>` render as a literal tag.\n setHighlightedCode(escapeHtml(code))\n }\n })\n\n // Line numbers generation\n const lineNumbers = () => {\n if (params()?.showLineNumbers === false) return []\n const code = params()?.code || ''\n const lines = code.split('\\n')\n const start = params()?.startLine || 1\n return lines.map((_, i) => start + i)\n }\n\n const handleCopy = async () => {\n const code = params()?.code\n if (code) {\n try {\n await navigator.clipboard.writeText(code)\n setIsCopied(true)\n setTimeout(() => setIsCopied(false), 2000)\n } catch (e) {\n console.error('Failed to copy code', e)\n }\n }\n }\n\n return (\n <ExpandableWrapper title={params()?.filename || params()?.language || strings.codeTitle} copyData={params()?.code} copyLabel={strings.codeCopy} toolbarVariant={props.toolbarVariant}>\n <div class={`w-full bg-gray-50 dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden text-sm flex flex-col ${isExpanded() ? 'flex-1 min-h-0' : ''}`}>\n {/* Header */}\n <div class=\"flex items-center justify-between px-4 py-2 bg-gray-100 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 shrink-0\">\n <div class=\"font-mono text-xs text-gray-600 dark:text-gray-400\">\n {params()?.filename || params()?.language || strings.codeTitle}\n </div>\n <div class=\"flex items-center gap-2\">\n {/* Search input (v6.2.0) */}\n <input\n type=\"text\"\n value={searchQuery()}\n onInput={(e) => setSearchQuery(e.currentTarget.value)}\n placeholder={strings.codeSearchPlaceholder}\n class=\"px-2 py-0.5 text-xs border border-gray-200 dark:border-gray-600 rounded bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-400 focus:border-blue-400 focus:ring-1 focus:ring-blue-400 outline-none w-32\"\n aria-label={strings.codeSearchAria}\n />\n {/* Download button (v6.2.0) */}\n <button\n onClick={handleDownload}\n class=\"text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 focus:outline-none transition-colors\"\n aria-label={strings.codeDownloadAria}\n title={strings.codeDownload}\n >\n <svg class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\" />\n </svg>\n </button>\n {/* Word wrap toggle */}\n <button\n onClick={() => setWordWrap(!wordWrap())}\n class={`focus:outline-none transition-colors ${wordWrap() ? 'text-blue-500 dark:text-blue-400' : 'text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200'}`}\n aria-label={strings.codeToggleWordWrap}\n title={wordWrap() ? strings.codeWordWrapDisable : strings.codeWordWrapEnable}\n >\n <svg class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M3 10h10a4 4 0 010 8H9m4 0l-3-3m3 3l-3 3M3 6h18M3 14h4\" />\n </svg>\n </button>\n {/* Copy button */}\n <button\n onClick={handleCopy}\n class=\"text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 focus:outline-none transition-colors\"\n aria-label={strings.codeCopy}\n title={strings.codeCopy}\n >\n <Show when={isCopied()} fallback={\n <svg class=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\" />\n </svg>\n }>\n <svg class=\"w-4 h-4 text-green-500\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13l4 4L19 7\" />\n </svg>\n </Show>\n </button>\n </div>\n </div>\n\n {/* Code Area */}\n <div\n class={`relative overflow-auto flex ${isExpanded() ? 'flex-1 min-h-0' : ''}`}\n style={!isExpanded() && params()?.maxHeight ? { 'max-height': params()?.maxHeight } : {}}\n >\n {/* Line Numbers */}\n <Show when={params()?.showLineNumbers !== false}>\n <div class=\"flex-none text-right select-none bg-gray-100 dark:bg-gray-800 border-r border-gray-200 dark:border-gray-700 py-4 px-2 text-gray-400 font-mono text-xs leading-5\">\n <For each={lineNumbers()}>\n {(num) => <div class=\"px-2\">{num}</div>}\n </For>\n </div>\n </Show>\n\n {/* Code Content - Sprint Ultimate U.1: data-theme for reactive theming */}\n <pre\n class=\"flex-1 m-0 p-4 font-mono text-gray-800 dark:text-gray-100 bg-transparent leading-5\"\n style={wordWrap() ? { 'white-space': 'pre-wrap', 'word-break': 'break-all' } : {}}\n data-theme={activeTheme()}\n >\n <code\n class={`hljs ${params()?.language ? `language-${params()?.language}` : ''}`}\n innerHTML={displayedHTML()}\n />\n </pre>\n </div>\n </div>\n </ExpandableWrapper>\n )\n}\n"],"names":["LANGUAGE_EXTENSIONS","typescript","tsx","javascript","jsx","python","ruby","go","rust","java","kotlin","swift","php","csharp","cpp","c","sql","json","yaml","toml","bash","shell","html","css","scss","markdown","xml","graphql","hljs","stylesLoaded","CodeBlockRenderer","props","strings","useMCPUIStrings","highlightedCode","setHighlightedCode","createSignal","isCopied","setIsCopied","isHljsLoaded","setIsHljsLoaded","activeTheme","setActiveTheme","wordWrap","setWordWrap","params","component","isExpanded","useExpanded","searchQuery","setSearchQuery","displayedHTML","q","trim","highlightQuery","handleDownload","code","lang","language","toLowerCase","ext","stem","filename","Date","now","replace","endsWith","blob","Blob","type","url","URL","createObjectURL","a","document","createElement","href","download","body","appendChild","click","removeChild","revokeObjectURL","createEffect","module","resolved","default","highlight","console","warn","e","isServer","Promise","all","paramTheme","theme","window","matchMedia","mediaQuery","matches","handleChange","addEventListener","onCleanup","removeEventListener","result","getLanguage","value","highlightAuto","escapeHtml","lineNumbers","showLineNumbers","lines","split","start","startLine","map","_","i","handleCopy","navigator","clipboard","writeText","setTimeout","error","_$createComponent","ExpandableWrapper","title","codeTitle","copyData","copyLabel","codeCopy","toolbarVariant","children","_el$","_$getNextElement","_tmpl$3","_el$2","firstChild","_el$3","_el$4","nextSibling","_el$5","_el$6","_el$7","_el$8","_el$0","_el$12","_el$13","_co$","_$getNextMarker","_el$10","_el$11","_$insert","$$input","currentTarget","$$click","Show","when","fallback","_tmpl$4","_tmpl$","_el$1","_tmpl$2","For","each","num","_el$15","_tmpl$5","_$effect","_p$","_v$","_v$2","codeSearchPlaceholder","_v$3","codeSearchAria","_v$4","codeDownloadAria","_v$5","codeDownload","_v$6","_v$7","codeToggleWordWrap","_v$8","codeWordWrapDisable","codeWordWrapEnable","_v$9","_v$0","_v$1","_v$10","maxHeight","_v$11","_v$12","_v$13","_v$14","_$className","t","_$setAttribute","o","n","s","h","r","d","l","u","_$style","w","m","f","_$setProperty","undefined","_$runHydrationEvents","_$delegateEvents"],"mappings":"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"}
|