@seed-ship/mcp-ui-solid 6.24.0 → 6.25.1
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 +42 -0
- package/README.md +47 -0
- package/dist/components/ActionGroupRenderer.cjs +6 -6
- package/dist/components/ActionGroupRenderer.cjs.map +1 -1
- package/dist/components/ActionGroupRenderer.js +6 -6
- package/dist/components/ActionGroupRenderer.js.map +1 -1
- package/dist/components/AutocompleteDropdown.cjs +6 -6
- package/dist/components/AutocompleteDropdown.cjs.map +1 -1
- package/dist/components/AutocompleteDropdown.js +6 -6
- package/dist/components/AutocompleteDropdown.js.map +1 -1
- package/dist/components/AutocompleteFormField.cjs +6 -5
- package/dist/components/AutocompleteFormField.cjs.map +1 -1
- package/dist/components/AutocompleteFormField.d.ts.map +1 -1
- package/dist/components/AutocompleteFormField.js +6 -5
- package/dist/components/AutocompleteFormField.js.map +1 -1
- package/dist/components/ChartJSRenderer.cjs +216 -6
- package/dist/components/ChartJSRenderer.cjs.map +1 -1
- package/dist/components/ChartJSRenderer.d.ts.map +1 -1
- package/dist/components/ChartJSRenderer.js +217 -7
- package/dist/components/ChartJSRenderer.js.map +1 -1
- package/dist/components/ChatPrompt.cjs +5 -5
- package/dist/components/ChatPrompt.cjs.map +1 -1
- package/dist/components/ChatPrompt.js +5 -5
- package/dist/components/ChatPrompt.js.map +1 -1
- package/dist/components/ComponentToolbar.cjs +5 -5
- package/dist/components/ComponentToolbar.cjs.map +1 -1
- package/dist/components/ComponentToolbar.js +5 -5
- package/dist/components/ComponentToolbar.js.map +1 -1
- package/dist/components/DegradedFallback.cjs +1 -1
- package/dist/components/DegradedFallback.cjs.map +1 -1
- package/dist/components/DegradedFallback.js +1 -1
- package/dist/components/DegradedFallback.js.map +1 -1
- package/dist/components/ExpandableWrapper.cjs +10 -7
- package/dist/components/ExpandableWrapper.cjs.map +1 -1
- package/dist/components/ExpandableWrapper.d.ts.map +1 -1
- package/dist/components/ExpandableWrapper.js +10 -7
- package/dist/components/ExpandableWrapper.js.map +1 -1
- package/dist/components/FormFieldRenderer.cjs +13 -12
- package/dist/components/FormFieldRenderer.cjs.map +1 -1
- package/dist/components/FormFieldRenderer.d.ts.map +1 -1
- package/dist/components/FormFieldRenderer.js +13 -12
- package/dist/components/FormFieldRenderer.js.map +1 -1
- package/dist/components/FormRenderer.cjs +1 -1
- package/dist/components/FormRenderer.cjs.map +1 -1
- package/dist/components/FormRenderer.js +1 -1
- package/dist/components/FormRenderer.js.map +1 -1
- package/dist/components/GenerativeUIErrorBoundary.cjs +1 -1
- package/dist/components/GenerativeUIErrorBoundary.cjs.map +1 -1
- package/dist/components/GenerativeUIErrorBoundary.js +1 -1
- package/dist/components/GenerativeUIErrorBoundary.js.map +1 -1
- package/dist/components/GhostText.cjs +2 -2
- package/dist/components/GhostText.cjs.map +1 -1
- package/dist/components/GhostText.js +2 -2
- package/dist/components/GhostText.js.map +1 -1
- package/dist/components/GraphRenderer.cjs +100 -29
- package/dist/components/GraphRenderer.cjs.map +1 -1
- package/dist/components/GraphRenderer.d.ts +1 -1
- package/dist/components/GraphRenderer.d.ts.map +1 -1
- package/dist/components/GraphRenderer.js +100 -29
- package/dist/components/GraphRenderer.js.map +1 -1
- package/dist/components/MissingValue.cjs +2 -2
- package/dist/components/MissingValue.cjs.map +1 -1
- package/dist/components/MissingValue.js +2 -2
- package/dist/components/MissingValue.js.map +1 -1
- package/dist/components/ModalRenderer.cjs +39 -31
- package/dist/components/ModalRenderer.cjs.map +1 -1
- package/dist/components/ModalRenderer.d.ts.map +1 -1
- package/dist/components/ModalRenderer.js +40 -32
- package/dist/components/ModalRenderer.js.map +1 -1
- package/dist/components/PortalDropdownMenu.cjs +6 -3
- package/dist/components/PortalDropdownMenu.cjs.map +1 -1
- package/dist/components/PortalDropdownMenu.d.ts.map +1 -1
- package/dist/components/PortalDropdownMenu.js +7 -4
- package/dist/components/PortalDropdownMenu.js.map +1 -1
- package/dist/components/ScratchpadPanel.cjs +38 -44
- package/dist/components/ScratchpadPanel.cjs.map +1 -1
- package/dist/components/ScratchpadPanel.d.ts.map +1 -1
- package/dist/components/ScratchpadPanel.js +38 -44
- package/dist/components/ScratchpadPanel.js.map +1 -1
- package/dist/components/UIResourceRenderer.cjs +20 -20
- package/dist/components/UIResourceRenderer.cjs.map +1 -1
- package/dist/components/UIResourceRenderer.js +20 -20
- package/dist/components/UIResourceRenderer.js.map +1 -1
- package/dist/components/chart-missing-plugin.cjs +4 -4
- package/dist/components/chart-missing-plugin.cjs.map +1 -1
- package/dist/components/chart-missing-plugin.d.ts +3 -1
- package/dist/components/chart-missing-plugin.d.ts.map +1 -1
- package/dist/components/chart-missing-plugin.js +4 -4
- package/dist/components/chart-missing-plugin.js.map +1 -1
- package/dist/utils/math-markdown.cjs +1 -1
- package/dist/utils/math-markdown.cjs.map +1 -1
- package/dist/utils/math-markdown.js +1 -1
- package/dist/utils/math-markdown.js.map +1 -1
- package/dist/utils/theme.cjs +91 -0
- package/dist/utils/theme.cjs.map +1 -0
- package/dist/utils/theme.d.ts +11 -0
- package/dist/utils/theme.d.ts.map +1 -0
- package/dist/utils/theme.js +91 -0
- package/dist/utils/theme.js.map +1 -0
- package/docs/SECURITY-DEPENDENCIES.md +81 -0
- package/docs/THEMING.md +205 -0
- package/package.json +5 -3
- package/src/components/ActionGroupRenderer.tsx +6 -6
- package/src/components/AutocompleteDropdown.tsx +17 -17
- package/src/components/AutocompleteFormField.tsx +10 -9
- package/src/components/ChartJSRenderer.tsx +483 -239
- package/src/components/ChatPrompt.tsx +16 -16
- package/src/components/ComponentToolbar.tsx +5 -5
- package/src/components/DegradedFallback.tsx +9 -9
- package/src/components/ExpandableWrapper.tsx +15 -11
- package/src/components/FormFieldRenderer.tsx +52 -51
- package/src/components/FormRenderer.tsx +12 -12
- package/src/components/GenerativeUIErrorBoundary.tsx +6 -6
- package/src/components/GhostText.tsx +7 -7
- package/src/components/GraphRenderer.tsx +83 -67
- package/src/components/MissingValue.tsx +2 -2
- package/src/components/ModalRenderer.tsx +11 -5
- package/src/components/PortalDropdownMenu.tsx +6 -2
- package/src/components/ScratchpadPanel.tsx +144 -141
- package/src/components/UIResourceRenderer.tsx +101 -101
- package/src/components/chart-missing-plugin.ts +5 -3
- package/src/styles/autocomplete.css +53 -53
- package/src/utils/math-markdown.ts +1 -1
- package/src/utils/theme.ts +101 -0
|
@@ -98,7 +98,7 @@ function CopyButton(props: { getText: () => string; title?: string; position?: '
|
|
|
98
98
|
return (
|
|
99
99
|
<button
|
|
100
100
|
onClick={handleCopy}
|
|
101
|
-
class={`${positionClasses()} opacity-60 hover:opacity-100 px-2 py-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700 transition-all shadow-sm z-10`}
|
|
101
|
+
class={`${positionClasses()} opacity-60 hover:opacity-100 px-2 py-1 bg-[color:var(--mcp-ui-surface,var(--color-white,#fff))] dark:bg-[color:var(--mcp-ui-surface,var(--color-gray-800,#1f2937))] border border-[color:var(--mcp-ui-border,var(--color-gray-200,#e5e7eb))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-600,#4b5563))] rounded-full hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-100,#f3f4f6))] dark:hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-700,#374151))] transition-all shadow-[var(--mcp-ui-shadow,var(--shadow-sm))] z-10`}
|
|
102
102
|
title={props.title || strings.copy}
|
|
103
103
|
aria-label={props.title || strings.copy}
|
|
104
104
|
data-mcp-ui-action="copy"
|
|
@@ -107,12 +107,12 @@ function CopyButton(props: { getText: () => string; title?: string; position?: '
|
|
|
107
107
|
<Show
|
|
108
108
|
when={!copied()}
|
|
109
109
|
fallback={
|
|
110
|
-
<svg class="w-3 h-3 text-green-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
110
|
+
<svg class="w-3 h-3 text-[color:var(--mcp-ui-success,var(--color-green-500))]" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
111
111
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
|
112
112
|
</svg>
|
|
113
113
|
}
|
|
114
114
|
>
|
|
115
|
-
<svg class="w-3 h-3 text-gray-500 dark:text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
115
|
+
<svg class="w-3 h-3 text-[color:var(--mcp-ui-fg-muted,var(--color-gray-500,#6b7280))] dark:text-[color:var(--mcp-ui-fg-subtle,var(--color-gray-400,#9ca3af))]" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
116
116
|
<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" />
|
|
117
117
|
</svg>
|
|
118
118
|
</Show>
|
|
@@ -259,8 +259,8 @@ function ChartRenderer(props: {
|
|
|
259
259
|
// Guard: if data or datasets missing, show error instead of crashing Chart.js
|
|
260
260
|
if (!params()?.data?.datasets) {
|
|
261
261
|
return (
|
|
262
|
-
<div class="p-4 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700">
|
|
263
|
-
<p class="text-red-500 dark:text-red-400 text-sm">{strings.chartInvalidData}</p>
|
|
262
|
+
<div class="p-4 bg-[color:var(--mcp-ui-surface,var(--color-white,#fff))] dark:bg-[color:var(--mcp-ui-surface,var(--color-gray-800,#1f2937))] rounded-lg border border-[color:var(--mcp-ui-border,var(--color-gray-200,#e5e7eb))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-700,#374151))]">
|
|
263
|
+
<p class="text-[color:var(--mcp-ui-danger,var(--color-red-500))] dark:text-[color:var(--mcp-ui-danger,var(--color-red-400))] text-sm">{strings.chartInvalidData}</p>
|
|
264
264
|
</div>
|
|
265
265
|
)
|
|
266
266
|
}
|
|
@@ -338,7 +338,7 @@ function ChartRenderer(props: {
|
|
|
338
338
|
<Show
|
|
339
339
|
when={useNative()}
|
|
340
340
|
fallback={
|
|
341
|
-
<div class="relative w-full h-full min-h-[300px] bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden">
|
|
341
|
+
<div class="relative w-full h-full min-h-[300px] bg-[color:var(--mcp-ui-surface,var(--color-white,#fff))] dark:bg-[color:var(--mcp-ui-surface,var(--color-gray-800,#1f2937))] rounded-lg shadow-[var(--mcp-ui-shadow,var(--shadow-sm))] border border-[color:var(--mcp-ui-border,var(--color-gray-200,#e5e7eb))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-700,#374151))] overflow-hidden">
|
|
342
342
|
{/* P1.7 — Chart.js missing and quickchart fallback not allowed:
|
|
343
343
|
show the chart data as a local table instead of an implicit
|
|
344
344
|
call to quickchart.io. */}
|
|
@@ -357,15 +357,15 @@ function ChartRenderer(props: {
|
|
|
357
357
|
|
|
358
358
|
<Show when={isLoading()}>
|
|
359
359
|
<div class="absolute inset-0 flex items-center justify-center">
|
|
360
|
-
<div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600" />
|
|
360
|
+
<div class="animate-spin rounded-full h-8 w-8 border-b-2 border-[color:var(--mcp-ui-accent-border,var(--color-blue-600))]" />
|
|
361
361
|
</div>
|
|
362
362
|
</Show>
|
|
363
363
|
|
|
364
364
|
<Show when={error()}>
|
|
365
365
|
<div class="absolute inset-0 flex items-center justify-center p-4">
|
|
366
366
|
<div class="text-center">
|
|
367
|
-
<p class="text-red-600 dark:text-red-400 text-sm font-medium">{strings.chartError}</p>
|
|
368
|
-
<p class="text-gray-600 dark:text-gray-400 text-xs mt-1">{error()}</p>
|
|
367
|
+
<p class="text-[color:var(--mcp-ui-danger,var(--color-red-600))] dark:text-[color:var(--mcp-ui-danger,var(--color-red-400))] text-sm font-medium">{strings.chartError}</p>
|
|
368
|
+
<p class="text-[color:var(--mcp-ui-fg-muted,var(--color-gray-600,#4b5563))] dark:text-[color:var(--mcp-ui-fg-subtle,var(--color-gray-400,#9ca3af))] text-xs mt-1">{error()}</p>
|
|
369
369
|
</div>
|
|
370
370
|
</div>
|
|
371
371
|
</Show>
|
|
@@ -373,7 +373,7 @@ function ChartRenderer(props: {
|
|
|
373
373
|
<Show when={iframeUrl() && !error()}>
|
|
374
374
|
<div class="w-full h-full p-4">
|
|
375
375
|
<Show when={params()?.title}>
|
|
376
|
-
<h3 class="text-sm font-semibold text-gray-900 dark:text-white mb-3">
|
|
376
|
+
<h3 class="text-sm font-semibold text-[color:var(--mcp-ui-fg,var(--color-gray-900,#111827))] dark:text-[color:var(--mcp-ui-fg,var(--color-white,#fff))] mb-3">
|
|
377
377
|
{params()?.title}
|
|
378
378
|
</h3>
|
|
379
379
|
</Show>
|
|
@@ -414,7 +414,7 @@ function ChartRenderer(props: {
|
|
|
414
414
|
* Smart cell value renderer that handles markdown links and other formats
|
|
415
415
|
*/
|
|
416
416
|
/** Class list carried by every `<mark>` that `highlightQuery` injects. */
|
|
417
|
-
const HIGHLIGHT_MARK_CLASS = 'bg-yellow-200 dark:bg-[
|
|
417
|
+
const HIGHLIGHT_MARK_CLASS = 'bg-[color:var(--mcp-ui-highlight,var(--color-yellow-200))] dark:bg-[color:var(--mcp-ui-highlight,#222F49)] text-inherit rounded px-0.5'
|
|
418
418
|
|
|
419
419
|
/**
|
|
420
420
|
* Wrap matches of `query` in `<mark>` tags within an HTML string.
|
|
@@ -553,12 +553,12 @@ function defaultCitationChip(
|
|
|
553
553
|
const safeDocName = encodeURIComponent(fileName || '')
|
|
554
554
|
const label = fileName ? `${fileName} - ${pageNum}` : `${pageNum}`
|
|
555
555
|
if (!verified) {
|
|
556
|
-
return `<span class="citation-ref inline-flex items-center gap-0.5 align-middle opacity-60"><span class="text-gray-500 line-through">[${label}]</span></span>`
|
|
556
|
+
return `<span class="citation-ref inline-flex items-center gap-0.5 align-middle opacity-60"><span class="text-[color:var(--mcp-ui-fg-muted,var(--color-gray-500,#6b7280))] line-through">[${label}]</span></span>`
|
|
557
557
|
}
|
|
558
558
|
return [
|
|
559
559
|
'<span class="citation-ref inline-flex items-center gap-0.5 align-middle">',
|
|
560
|
-
`<span class="text-gray-500">[${label}]</span>`,
|
|
561
|
-
'<button class="inline-flex items-center ml-0.5 px-1 py-0.5 text-xs bg-gray-800 hover:bg-gray-700 border border-gray-600 hover:border-teal-500 rounded cursor-pointer transition-colors align-middle"',
|
|
560
|
+
`<span class="text-[color:var(--mcp-ui-fg-muted,var(--color-gray-500,#6b7280))]">[${label}]</span>`,
|
|
561
|
+
'<button class="inline-flex items-center ml-0.5 px-1 py-0.5 text-xs bg-[color:var(--mcp-ui-surface,var(--color-gray-800,#1f2937))] hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-700,#374151))] border border-[color:var(--mcp-ui-border,var(--color-gray-600,#4b5563))] hover:border-[color:var(--mcp-ui-info-border,var(--color-teal-500))] rounded cursor-pointer transition-colors align-middle"',
|
|
562
562
|
` data-citation-page="${pageNum}"`,
|
|
563
563
|
` data-citation-doc="${safeDocName}"`,
|
|
564
564
|
' data-citation-verified="true"',
|
|
@@ -616,7 +616,7 @@ export function renderCellValue(value: any, citationCtx?: CitationCtx, mathRende
|
|
|
616
616
|
const label = value.name || value.label || value.title || value.url
|
|
617
617
|
const sanitizedLabel = sanitizeHtml(String(label))
|
|
618
618
|
const sanitizedUrl = sanitizeHtml(String(value.url))
|
|
619
|
-
const anchor = `<a href="${sanitizedUrl}" target="_blank" rel="noopener noreferrer" class="text-blue-600 dark:text-blue-400 hover:underline">${sanitizedLabel}</a>`
|
|
619
|
+
const anchor = `<a href="${sanitizedUrl}" target="_blank" rel="noopener noreferrer" class="text-[color:var(--mcp-ui-accent,var(--color-blue-600))] dark:text-[color:var(--mcp-ui-accent,var(--color-blue-400))] hover:underline">${sanitizedLabel}</a>`
|
|
620
620
|
// Re-sanitize the composed anchor: sanitizing the bare `url` string
|
|
621
621
|
// leaves quotes and `javascript:` untouched, so a crafted value could
|
|
622
622
|
// otherwise break out of the attribute or smuggle a scriptable href.
|
|
@@ -675,7 +675,7 @@ export function renderCellValue(value: any, citationCtx?: CitationCtx, mathRende
|
|
|
675
675
|
// Replace all markdown links with HTML links
|
|
676
676
|
const htmlValue = strValue.replace(
|
|
677
677
|
/\[([^\]]+)\]\(([^)]+)\)/g,
|
|
678
|
-
'<a href="$2" target="_blank" rel="noopener noreferrer" class="text-blue-600 dark:text-blue-400 hover:underline">$1</a>'
|
|
678
|
+
'<a href="$2" target="_blank" rel="noopener noreferrer" class="text-[color:var(--mcp-ui-accent,var(--color-blue-600))] dark:text-[color:var(--mcp-ui-accent,var(--color-blue-400))] hover:underline">$1</a>'
|
|
679
679
|
)
|
|
680
680
|
return sanitizeHtml(htmlValue, SANITIZE_PROFILES.cellLink)
|
|
681
681
|
}
|
|
@@ -1035,13 +1035,13 @@ function TableRenderer(props: {
|
|
|
1035
1035
|
|
|
1036
1036
|
// Standard table body (non-virtualized) — uses client pagination when active
|
|
1037
1037
|
const StandardTableBody = () => (
|
|
1038
|
-
<tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">
|
|
1038
|
+
<tbody class="bg-[color:var(--mcp-ui-surface,var(--color-white,#fff))] dark:bg-[color:var(--mcp-ui-surface,var(--color-gray-800,#1f2937))] divide-y divide-[color:var(--mcp-ui-border,var(--color-gray-200,#e5e7eb))] dark:divide-[color:var(--mcp-ui-border,var(--color-gray-700,#374151))]">
|
|
1039
1039
|
<For each={clientVisibleRows().slice(0, DEFAULT_RESOURCE_LIMITS.maxTableRows)}>
|
|
1040
1040
|
{(row: any, i) => (
|
|
1041
|
-
<tr class={`hover:bg-gray-50 dark:hover:bg-gray-700
|
|
1041
|
+
<tr class={`hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-50,#f9fafb))] dark:hover:bg-[color:var(--mcp-ui-surface-hover,color-mix(in_oklab,var(--color-gray-700,#374151)_50%,transparent))] transition-colors ${i() % 2 === 0 ? 'bg-[color:var(--mcp-ui-surface,var(--color-white,#fff))] dark:bg-[color:var(--mcp-ui-surface,var(--color-gray-800,#1f2937))]' : 'bg-[color:var(--mcp-ui-surface-muted,color-mix(in_oklab,var(--color-gray-50,#f9fafb)_30%,transparent))] dark:bg-[color:var(--mcp-ui-surface,color-mix(in_oklab,var(--color-gray-800,#1f2937)_50%,transparent))]'}`}>
|
|
1042
1042
|
<For each={tableParams.columns}>
|
|
1043
1043
|
{(column: any) => (
|
|
1044
|
-
<td class="px-6 py-4 text-sm text-gray-700 dark:text-gray-200 whitespace-normal break-words leading-relaxed first:pl-6 last:pr-6">
|
|
1044
|
+
<td class="px-6 py-4 text-sm text-[color:var(--mcp-ui-fg,var(--color-gray-700,#374151))] dark:text-[color:var(--mcp-ui-fg,var(--color-gray-200,#e5e7eb))] whitespace-normal break-words leading-relaxed first:pl-6 last:pr-6">
|
|
1045
1045
|
<Show
|
|
1046
1046
|
when={!isMissingCellValue(row[column.key])}
|
|
1047
1047
|
fallback={<MissingValueMark />}
|
|
@@ -1069,7 +1069,7 @@ function TableRenderer(props: {
|
|
|
1069
1069
|
|
|
1070
1070
|
return (
|
|
1071
1071
|
<tbody
|
|
1072
|
-
class="bg-white dark:bg-gray-800 relative"
|
|
1072
|
+
class="bg-[color:var(--mcp-ui-surface,var(--color-white,#fff))] dark:bg-[color:var(--mcp-ui-surface,var(--color-gray-800,#1f2937))] relative"
|
|
1073
1073
|
style={{ height: `${totalSize}px` }}
|
|
1074
1074
|
>
|
|
1075
1075
|
<For each={items}>
|
|
@@ -1077,7 +1077,7 @@ function TableRenderer(props: {
|
|
|
1077
1077
|
const row = tableParams.rows[virtualRow.index]
|
|
1078
1078
|
return (
|
|
1079
1079
|
<tr
|
|
1080
|
-
class={`hover:bg-gray-50 dark:hover:bg-gray-700
|
|
1080
|
+
class={`hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-50,#f9fafb))] dark:hover:bg-[color:var(--mcp-ui-surface-hover,color-mix(in_oklab,var(--color-gray-700,#374151)_50%,transparent))] transition-colors absolute left-0 right-0 ${virtualRow.index % 2 === 0 ? 'bg-[color:var(--mcp-ui-surface,var(--color-white,#fff))] dark:bg-[color:var(--mcp-ui-surface,var(--color-gray-800,#1f2937))]' : 'bg-[color:var(--mcp-ui-surface-muted,color-mix(in_oklab,var(--color-gray-50,#f9fafb)_30%,transparent))] dark:bg-[color:var(--mcp-ui-surface,color-mix(in_oklab,var(--color-gray-800,#1f2937)_50%,transparent))]'}`}
|
|
1081
1081
|
style={{
|
|
1082
1082
|
height: `${rowHeight}px`,
|
|
1083
1083
|
transform: `translateY(${virtualRow.start}px)`
|
|
@@ -1085,7 +1085,7 @@ function TableRenderer(props: {
|
|
|
1085
1085
|
>
|
|
1086
1086
|
<For each={tableParams.columns}>
|
|
1087
1087
|
{(column: any) => (
|
|
1088
|
-
<td class="px-6 py-4 text-sm text-gray-700 dark:text-gray-200 whitespace-normal break-words leading-relaxed first:pl-6 last:pr-6">
|
|
1088
|
+
<td class="px-6 py-4 text-sm text-[color:var(--mcp-ui-fg,var(--color-gray-700,#374151))] dark:text-[color:var(--mcp-ui-fg,var(--color-gray-200,#e5e7eb))] whitespace-normal break-words leading-relaxed first:pl-6 last:pr-6">
|
|
1089
1089
|
<Show
|
|
1090
1090
|
when={!isMissingCellValue(row[column.key])}
|
|
1091
1091
|
fallback={<MissingValueMark />}
|
|
@@ -1105,7 +1105,7 @@ function TableRenderer(props: {
|
|
|
1105
1105
|
|
|
1106
1106
|
return (
|
|
1107
1107
|
<ExpandableWrapper title={tableParams.title || strings.tableTitle} copyData={getTableCSV()} copyLabel={strings.tableCopyCsv} toolbarVariant={props.toolbarVariant} onExpandedChange={setSelfExpanded}>
|
|
1108
|
-
<div class={`relative w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden group ${
|
|
1108
|
+
<div class={`relative w-full bg-[color:var(--mcp-ui-surface,var(--color-white,#fff))] dark:bg-[color:var(--mcp-ui-surface,var(--color-gray-800,#1f2937))] rounded-lg shadow-[var(--mcp-ui-shadow,var(--shadow-sm))] border border-[color:var(--mcp-ui-border,var(--color-gray-200,#e5e7eb))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-700,#374151))] overflow-hidden group ${
|
|
1109
1109
|
isExpanded() ? 'flex-1 min-h-0 flex flex-col' : 'h-full'
|
|
1110
1110
|
} ${tableParams.className || ''}`}>
|
|
1111
1111
|
<Show when={exportable} fallback={<CopyButton getText={getTableCSV} title={strings.tableCopyCsv} position="top-right" />}>
|
|
@@ -1113,13 +1113,13 @@ function TableRenderer(props: {
|
|
|
1113
1113
|
<button
|
|
1114
1114
|
ref={exportTriggerRef}
|
|
1115
1115
|
onClick={() => setShowExportMenu(!showExportMenu())}
|
|
1116
|
-
class="opacity-60 hover:opacity-100 px-2 py-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700 transition-all shadow-sm"
|
|
1116
|
+
class="opacity-60 hover:opacity-100 px-2 py-1 bg-[color:var(--mcp-ui-surface,var(--color-white,#fff))] dark:bg-[color:var(--mcp-ui-surface,var(--color-gray-800,#1f2937))] border border-[color:var(--mcp-ui-border,var(--color-gray-200,#e5e7eb))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-600,#4b5563))] rounded-full hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-100,#f3f4f6))] dark:hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-700,#374151))] transition-all shadow-[var(--mcp-ui-shadow,var(--shadow-sm))]"
|
|
1117
1117
|
title={strings.tableExport}
|
|
1118
1118
|
aria-label={strings.tableExport}
|
|
1119
1119
|
aria-haspopup="menu"
|
|
1120
1120
|
aria-expanded={showExportMenu()}
|
|
1121
1121
|
>
|
|
1122
|
-
<svg class="w-3 h-3 text-gray-500 dark:text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
1122
|
+
<svg class="w-3 h-3 text-[color:var(--mcp-ui-fg-muted,var(--color-gray-500,#6b7280))] dark:text-[color:var(--mcp-ui-fg-subtle,var(--color-gray-400,#9ca3af))]" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
1123
1123
|
<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" />
|
|
1124
1124
|
</svg>
|
|
1125
1125
|
</button>
|
|
@@ -1130,23 +1130,23 @@ function TableRenderer(props: {
|
|
|
1130
1130
|
width={144}
|
|
1131
1131
|
>
|
|
1132
1132
|
<Show when={(exportFormats as string[]).includes('tsv')}>
|
|
1133
|
-
<button onClick={() => handleExport('tsv')} class="w-full text-left px-3 py-1.5 hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300">{strings.tableCopyTsv}</button>
|
|
1133
|
+
<button onClick={() => handleExport('tsv')} class="w-full text-left px-3 py-1.5 hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-100,#f3f4f6))] dark:hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-700,#374151))] text-[color:var(--mcp-ui-fg,var(--color-gray-700,#374151))] dark:text-[color:var(--mcp-ui-fg,var(--color-gray-300,#d1d5db))]">{strings.tableCopyTsv}</button>
|
|
1134
1134
|
</Show>
|
|
1135
1135
|
<Show when={(exportFormats as string[]).includes('csv')}>
|
|
1136
|
-
<button onClick={() => handleExport('csv')} class="w-full text-left px-3 py-1.5 hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300">{strings.tableDownloadCsv}</button>
|
|
1136
|
+
<button onClick={() => handleExport('csv')} class="w-full text-left px-3 py-1.5 hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-100,#f3f4f6))] dark:hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-700,#374151))] text-[color:var(--mcp-ui-fg,var(--color-gray-700,#374151))] dark:text-[color:var(--mcp-ui-fg,var(--color-gray-300,#d1d5db))]">{strings.tableDownloadCsv}</button>
|
|
1137
1137
|
</Show>
|
|
1138
1138
|
<Show when={(exportFormats as string[]).includes('json')}>
|
|
1139
|
-
<button onClick={() => handleExport('json')} class="w-full text-left px-3 py-1.5 hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300">{strings.tableDownloadJson}</button>
|
|
1139
|
+
<button onClick={() => handleExport('json')} class="w-full text-left px-3 py-1.5 hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-100,#f3f4f6))] dark:hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-700,#374151))] text-[color:var(--mcp-ui-fg,var(--color-gray-700,#374151))] dark:text-[color:var(--mcp-ui-fg,var(--color-gray-300,#d1d5db))]">{strings.tableDownloadJson}</button>
|
|
1140
1140
|
</Show>
|
|
1141
1141
|
</PortalDropdownMenu>
|
|
1142
1142
|
</div>
|
|
1143
1143
|
</Show>
|
|
1144
1144
|
<div class={`p-4 ${isExpanded() ? 'flex-1 min-h-0 flex flex-col' : ''}`}>
|
|
1145
1145
|
<Show when={tableParams.title}>
|
|
1146
|
-
<h3 id={`${tableId}-title`} class="text-sm font-semibold text-gray-900 dark:text-white mb-3 flex-shrink-0">
|
|
1146
|
+
<h3 id={`${tableId}-title`} class="text-sm font-semibold text-[color:var(--mcp-ui-fg,var(--color-gray-900,#111827))] dark:text-[color:var(--mcp-ui-fg,var(--color-white,#fff))] mb-3 flex-shrink-0">
|
|
1147
1147
|
{tableParams.title}
|
|
1148
1148
|
<Show when={isVirtualizing()}>
|
|
1149
|
-
<span class="ml-2 text-xs font-normal text-gray-400">
|
|
1149
|
+
<span class="ml-2 text-xs font-normal text-[color:var(--mcp-ui-fg-subtle,var(--color-gray-400,#9ca3af))]">
|
|
1150
1150
|
{formatMCPUIString(strings.tableVirtualizedRows, { count: tableParams.rows?.length ?? 0 })}
|
|
1151
1151
|
</span>
|
|
1152
1152
|
</Show>
|
|
@@ -1156,25 +1156,25 @@ function TableRenderer(props: {
|
|
|
1156
1156
|
{/* Search input (v4.3.3) */}
|
|
1157
1157
|
<Show when={isSearchable()}>
|
|
1158
1158
|
<div class="relative mb-3">
|
|
1159
|
-
<span class="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 pointer-events-none text-sm">{'\uD83D\uDD0D'}</span>
|
|
1159
|
+
<span class="absolute left-3 top-1/2 -translate-y-1/2 text-[color:var(--mcp-ui-fg-subtle,var(--color-gray-400,#9ca3af))] pointer-events-none text-sm">{'\uD83D\uDD0D'}</span>
|
|
1160
1160
|
<input
|
|
1161
1161
|
type="text"
|
|
1162
1162
|
value={searchQuery()}
|
|
1163
1163
|
onInput={(e) => handleSearch(e.currentTarget.value)}
|
|
1164
1164
|
placeholder={searchPlaceholder()}
|
|
1165
|
-
class="w-full max-w-xs min-w-[200px] pl-8 pr-8 py-1.5 text-sm border border-gray-200 dark:border-gray-600 rounded-md 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"
|
|
1165
|
+
class="w-full max-w-xs min-w-[200px] pl-8 pr-8 py-1.5 text-sm border border-[color:var(--mcp-ui-border,var(--color-gray-200,#e5e7eb))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-600,#4b5563))] rounded-md bg-[color:var(--mcp-ui-surface,var(--color-white,#fff))] dark:bg-[color:var(--mcp-ui-surface-muted,var(--color-gray-700,#374151))] text-[color:var(--mcp-ui-fg,var(--color-gray-900,#111827))] dark:text-[color:var(--mcp-ui-fg,var(--color-white,#fff))] placeholder-[color:var(--mcp-ui-fg-subtle,var(--color-gray-400,#9ca3af))] focus:border-[color:var(--mcp-ui-focus,var(--color-blue-400))] focus:ring-1 focus:ring-[color:var(--mcp-ui-focus,var(--color-blue-400))] outline-none"
|
|
1166
1166
|
/>
|
|
1167
1167
|
<Show when={searchQuery()}>
|
|
1168
1168
|
<button
|
|
1169
1169
|
type="button"
|
|
1170
1170
|
onClick={() => { handleSearch(''); setSearchQuery(''); setDebouncedQuery('') }}
|
|
1171
|
-
class="absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 text-sm"
|
|
1171
|
+
class="absolute right-2 top-1/2 -translate-y-1/2 text-[color:var(--mcp-ui-fg-subtle,var(--color-gray-400,#9ca3af))] hover:text-[color:var(--mcp-ui-fg-muted,var(--color-gray-600,#4b5563))] dark:hover:text-[color:var(--mcp-ui-fg,var(--color-gray-300,#d1d5db))] text-sm"
|
|
1172
1172
|
aria-label={strings.tableClearSearch}
|
|
1173
1173
|
>×</button>
|
|
1174
1174
|
</Show>
|
|
1175
1175
|
</div>
|
|
1176
1176
|
<Show when={debouncedQuery() && filteredRows().length !== sortedRows().length}>
|
|
1177
|
-
<p class="text-xs text-gray-500 dark:text-gray-400 mb-2">
|
|
1177
|
+
<p class="text-xs text-[color:var(--mcp-ui-fg-muted,var(--color-gray-500,#6b7280))] dark:text-[color:var(--mcp-ui-fg-subtle,var(--color-gray-400,#9ca3af))] mb-2">
|
|
1178
1178
|
{formatMCPUIString(
|
|
1179
1179
|
filteredRows().length === 1 ? strings.tableSearchResultsOne : strings.tableSearchResultsMany,
|
|
1180
1180
|
{ count: filteredRows().length, total: sortedRows().length }
|
|
@@ -1213,16 +1213,16 @@ function TableRenderer(props: {
|
|
|
1213
1213
|
tabindex="0"
|
|
1214
1214
|
>
|
|
1215
1215
|
<table
|
|
1216
|
-
class="min-w-full divide-y divide-gray-200 dark:divide-gray-700 border-separate border-spacing-0"
|
|
1216
|
+
class="min-w-full divide-y divide-[color:var(--mcp-ui-border,var(--color-gray-200,#e5e7eb))] dark:divide-[color:var(--mcp-ui-border,var(--color-gray-700,#374151))] border-separate border-spacing-0"
|
|
1217
1217
|
aria-labelledby={tableParams.title ? `${tableId}-title` : undefined}
|
|
1218
1218
|
>
|
|
1219
|
-
<thead class="bg-gray-100 dark:bg-gray-900 sticky top-0 z-10">
|
|
1219
|
+
<thead class="bg-[color:var(--mcp-ui-surface-muted,var(--color-gray-100,#f3f4f6))] dark:bg-[color:var(--mcp-ui-surface,var(--color-gray-900,#111827))] sticky top-0 z-10">
|
|
1220
1220
|
<tr>
|
|
1221
1221
|
<For each={tableParams.columns}>
|
|
1222
1222
|
{(column: any) => (
|
|
1223
1223
|
<th
|
|
1224
1224
|
scope="col"
|
|
1225
|
-
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700 first:pl-6 last:pr-6 bg-gray-100 dark:bg-gray-900 cursor-pointer select-none hover:bg-gray-200 dark:hover:bg-gray-800 transition-colors"
|
|
1225
|
+
class="px-6 py-3 text-left text-xs font-semibold text-[color:var(--mcp-ui-fg-muted,var(--color-gray-500,#6b7280))] dark:text-[color:var(--mcp-ui-fg-subtle,var(--color-gray-400,#9ca3af))] uppercase tracking-wider border-b border-[color:var(--mcp-ui-border,var(--color-gray-200,#e5e7eb))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-700,#374151))] first:pl-6 last:pr-6 bg-[color:var(--mcp-ui-surface-muted,var(--color-gray-100,#f3f4f6))] dark:bg-[color:var(--mcp-ui-surface,var(--color-gray-900,#111827))] cursor-pointer select-none hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-200,#e5e7eb))] dark:hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-800,#1f2937))] transition-colors"
|
|
1226
1226
|
style={column.width ? { width: column.width } : {}}
|
|
1227
1227
|
on:click={() => handleSort(column.key)}
|
|
1228
1228
|
title={formatMCPUIString(strings.sortBy, { column: column.label })}
|
|
@@ -1233,7 +1233,7 @@ function TableRenderer(props: {
|
|
|
1233
1233
|
class="text-[10px] leading-none"
|
|
1234
1234
|
classList={{
|
|
1235
1235
|
'opacity-30': sortKey() !== column.key,
|
|
1236
|
-
'opacity-100 text-blue-600 dark:text-blue-400': sortKey() === column.key,
|
|
1236
|
+
'opacity-100 text-[color:var(--mcp-ui-accent,var(--color-blue-600))] dark:text-[color:var(--mcp-ui-accent,var(--color-blue-400))]': sortKey() === column.key,
|
|
1237
1237
|
}}
|
|
1238
1238
|
>
|
|
1239
1239
|
{sortIndicator(column.key)}
|
|
@@ -1257,7 +1257,7 @@ function TableRenderer(props: {
|
|
|
1257
1257
|
|
|
1258
1258
|
{/* Server-side pagination (legacy) */}
|
|
1259
1259
|
<Show when={tableParams.pagination}>
|
|
1260
|
-
<div class="mt-3 flex items-center justify-between text-xs text-gray-500 dark:text-gray-400">
|
|
1260
|
+
<div class="mt-3 flex items-center justify-between text-xs text-[color:var(--mcp-ui-fg-muted,var(--color-gray-500,#6b7280))] dark:text-[color:var(--mcp-ui-fg-subtle,var(--color-gray-400,#9ca3af))]">
|
|
1261
1261
|
<span>
|
|
1262
1262
|
{formatMCPUIString(strings.tableServerPageRange, {
|
|
1263
1263
|
start: tableParams.pagination.currentPage * tableParams.pagination.pageSize + 1,
|
|
@@ -1273,14 +1273,14 @@ function TableRenderer(props: {
|
|
|
1273
1273
|
|
|
1274
1274
|
{/* Client-side pagination (v4.3.7) */}
|
|
1275
1275
|
<Show when={needsClientPagination()}>
|
|
1276
|
-
<div class="mt-3 flex items-center justify-between text-xs text-gray-500 dark:text-gray-400">
|
|
1276
|
+
<div class="mt-3 flex items-center justify-between text-xs text-[color:var(--mcp-ui-fg-muted,var(--color-gray-500,#6b7280))] dark:text-[color:var(--mcp-ui-fg-subtle,var(--color-gray-400,#9ca3af))]">
|
|
1277
1277
|
<span>
|
|
1278
1278
|
{clientRangeStart()}–{clientRangeEnd()} / {filteredRows().length.toLocaleString(strings.locale)}
|
|
1279
1279
|
</span>
|
|
1280
1280
|
<div class="flex items-center gap-2">
|
|
1281
1281
|
<button
|
|
1282
1282
|
type="button"
|
|
1283
|
-
class="px-2 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-700 disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
|
|
1283
|
+
class="px-2 py-1 rounded hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-100,#f3f4f6))] dark:hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-700,#374151))] disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
|
|
1284
1284
|
disabled={clientPage() === 0}
|
|
1285
1285
|
onClick={() => setClientPage(p => p - 1)}
|
|
1286
1286
|
aria-label={strings.paginationPrevious}
|
|
@@ -1291,7 +1291,7 @@ function TableRenderer(props: {
|
|
|
1291
1291
|
<span aria-live="polite">{clientPage() + 1} / {clientTotalPages()}</span>
|
|
1292
1292
|
<button
|
|
1293
1293
|
type="button"
|
|
1294
|
-
class="px-2 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-700 disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
|
|
1294
|
+
class="px-2 py-1 rounded hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-100,#f3f4f6))] dark:hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-700,#374151))] disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
|
|
1295
1295
|
disabled={clientPage() >= clientTotalPages() - 1}
|
|
1296
1296
|
onClick={() => setClientPage(p => p + 1)}
|
|
1297
1297
|
aria-label={strings.paginationNext}
|
|
@@ -1302,7 +1302,7 @@ function TableRenderer(props: {
|
|
|
1302
1302
|
{/* Page size selector — fullscreen only */}
|
|
1303
1303
|
<Show when={isExpanded() && filteredRows().length > 10}>
|
|
1304
1304
|
<select
|
|
1305
|
-
class="ml-2 px-1 py-0.5 text-xs border border-gray-200 dark:border-gray-600 rounded bg-white dark:bg-gray-700 text-gray-700 dark:text-gray-300"
|
|
1305
|
+
class="ml-2 px-1 py-0.5 text-xs border border-[color:var(--mcp-ui-border,var(--color-gray-200,#e5e7eb))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-600,#4b5563))] rounded bg-[color:var(--mcp-ui-surface,var(--color-white,#fff))] dark:bg-[color:var(--mcp-ui-surface-muted,var(--color-gray-700,#374151))] text-[color:var(--mcp-ui-fg,var(--color-gray-700,#374151))] dark:text-[color:var(--mcp-ui-fg,var(--color-gray-300,#d1d5db))]"
|
|
1306
1306
|
value={clientPageSize()}
|
|
1307
1307
|
onChange={(e) => handlePageSizeChange(Number(e.currentTarget.value))}
|
|
1308
1308
|
aria-label={strings.paginationPageSize}
|
|
@@ -1312,7 +1312,7 @@ function TableRenderer(props: {
|
|
|
1312
1312
|
{(opt) => <option value={opt.value}>{opt.label}</option>}
|
|
1313
1313
|
</For>
|
|
1314
1314
|
</select>
|
|
1315
|
-
<span class="text-gray-400">{strings.perPageSuffix}</span>
|
|
1315
|
+
<span class="text-[color:var(--mcp-ui-fg-subtle,var(--color-gray-400,#9ca3af))]">{strings.perPageSuffix}</span>
|
|
1316
1316
|
</Show>
|
|
1317
1317
|
</div>
|
|
1318
1318
|
</div>
|
|
@@ -1339,17 +1339,17 @@ function MetricRenderer(props: { component: UIComponent }) {
|
|
|
1339
1339
|
}
|
|
1340
1340
|
|
|
1341
1341
|
return (
|
|
1342
|
-
<div class="relative w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-4 group">
|
|
1342
|
+
<div class="relative w-full h-full bg-[color:var(--mcp-ui-surface,var(--color-white,#fff))] dark:bg-[color:var(--mcp-ui-surface,var(--color-gray-800,#1f2937))] rounded-lg shadow-[var(--mcp-ui-shadow,var(--shadow-sm))] border border-[color:var(--mcp-ui-border,var(--color-gray-200,#e5e7eb))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-700,#374151))] p-4 group">
|
|
1343
1343
|
<CopyButton getText={getMetricText} title={strings.copyMetric} position="top-right" />
|
|
1344
1344
|
<div class="flex flex-col h-full justify-between">
|
|
1345
1345
|
<div>
|
|
1346
|
-
<p class="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide">
|
|
1346
|
+
<p class="text-xs font-medium text-[color:var(--mcp-ui-fg-muted,var(--color-gray-500,#6b7280))] dark:text-[color:var(--mcp-ui-fg-subtle,var(--color-gray-400,#9ca3af))] uppercase tracking-wide">
|
|
1347
1347
|
{metricParams.title}
|
|
1348
1348
|
</p>
|
|
1349
1349
|
<div class="mt-2 flex items-baseline">
|
|
1350
|
-
<p class="text-2xl font-semibold text-gray-900 dark:text-white">{metricParams.value}</p>
|
|
1350
|
+
<p class="text-2xl font-semibold text-[color:var(--mcp-ui-fg,var(--color-gray-900,#111827))] dark:text-[color:var(--mcp-ui-fg,var(--color-white,#fff))]">{metricParams.value}</p>
|
|
1351
1351
|
<Show when={metricParams.unit}>
|
|
1352
|
-
<span class="ml-2 text-sm font-medium text-gray-500 dark:text-gray-400">
|
|
1352
|
+
<span class="ml-2 text-sm font-medium text-[color:var(--mcp-ui-fg-muted,var(--color-gray-500,#6b7280))] dark:text-[color:var(--mcp-ui-fg-subtle,var(--color-gray-400,#9ca3af))]">
|
|
1353
1353
|
{metricParams.unit}
|
|
1354
1354
|
</span>
|
|
1355
1355
|
</Show>
|
|
@@ -1360,10 +1360,10 @@ function MetricRenderer(props: { component: UIComponent }) {
|
|
|
1360
1360
|
<div class="mt-3 flex items-center">
|
|
1361
1361
|
<span
|
|
1362
1362
|
class={`text-sm font-medium ${metricParams.trend.direction === 'up'
|
|
1363
|
-
? 'text-green-600 dark:text-green-400'
|
|
1363
|
+
? 'text-[color:var(--mcp-ui-success,var(--color-green-600))] dark:text-[color:var(--mcp-ui-success,var(--color-green-400))]'
|
|
1364
1364
|
: metricParams.trend.direction === 'down'
|
|
1365
|
-
? 'text-red-600 dark:text-red-400'
|
|
1366
|
-
: 'text-gray-600 dark:text-gray-400'
|
|
1365
|
+
? 'text-[color:var(--mcp-ui-danger,var(--color-red-600))] dark:text-[color:var(--mcp-ui-danger,var(--color-red-400))]'
|
|
1366
|
+
: 'text-[color:var(--mcp-ui-fg-muted,var(--color-gray-600,#4b5563))] dark:text-[color:var(--mcp-ui-fg-subtle,var(--color-gray-400,#9ca3af))]'
|
|
1367
1367
|
}`}
|
|
1368
1368
|
>
|
|
1369
1369
|
{metricParams.trend.direction === 'up'
|
|
@@ -1377,7 +1377,7 @@ function MetricRenderer(props: { component: UIComponent }) {
|
|
|
1377
1377
|
</Show>
|
|
1378
1378
|
|
|
1379
1379
|
<Show when={metricParams.subtitle}>
|
|
1380
|
-
<p class="mt-2 text-xs text-gray-500 dark:text-gray-400">{metricParams.subtitle}</p>
|
|
1380
|
+
<p class="mt-2 text-xs text-[color:var(--mcp-ui-fg-muted,var(--color-gray-500,#6b7280))] dark:text-[color:var(--mcp-ui-fg-subtle,var(--color-gray-400,#9ca3af))]">{metricParams.subtitle}</p>
|
|
1381
1381
|
</Show>
|
|
1382
1382
|
</div>
|
|
1383
1383
|
</div>
|
|
@@ -1468,7 +1468,7 @@ function TextRenderer(props: { component: UIComponent }) {
|
|
|
1468
1468
|
<Show
|
|
1469
1469
|
when={imageData()}
|
|
1470
1470
|
fallback={
|
|
1471
|
-
<div class="relative w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-4 group">
|
|
1471
|
+
<div class="relative w-full h-full bg-[color:var(--mcp-ui-surface,var(--color-white,#fff))] dark:bg-[color:var(--mcp-ui-surface,var(--color-gray-800,#1f2937))] rounded-lg shadow-[var(--mcp-ui-shadow,var(--shadow-sm))] border border-[color:var(--mcp-ui-border,var(--color-gray-200,#e5e7eb))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-700,#374151))] p-4 group">
|
|
1472
1472
|
<CopyButton getText={getTextContent} title={strings.copyText} position="top-right" />
|
|
1473
1473
|
<SafeHtml
|
|
1474
1474
|
class={`prose prose-sm dark:prose-invert max-w-none ${textParams.className || ''}`}
|
|
@@ -1483,13 +1483,13 @@ function TextRenderer(props: { component: UIComponent }) {
|
|
|
1483
1483
|
<img
|
|
1484
1484
|
src={data().imageUrl}
|
|
1485
1485
|
alt={data().alt}
|
|
1486
|
-
class="max-w-full max-h-[400px] object-contain rounded shadow-sm hover:opacity-90 transition-opacity"
|
|
1486
|
+
class="max-w-full max-h-[400px] object-contain rounded shadow-[var(--mcp-ui-shadow,var(--shadow-sm))] hover:opacity-90 transition-opacity"
|
|
1487
1487
|
loading="lazy"
|
|
1488
1488
|
/>
|
|
1489
1489
|
)
|
|
1490
1490
|
return (
|
|
1491
|
-
<div class="w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden flex flex-col">
|
|
1492
|
-
<div class="flex-1 flex items-center justify-center p-4 bg-gray-50 dark:bg-gray-900 min-h-[200px]">
|
|
1491
|
+
<div class="w-full h-full bg-[color:var(--mcp-ui-surface,var(--color-white,#fff))] dark:bg-[color:var(--mcp-ui-surface,var(--color-gray-800,#1f2937))] rounded-lg shadow-[var(--mcp-ui-shadow,var(--shadow-sm))] border border-[color:var(--mcp-ui-border,var(--color-gray-200,#e5e7eb))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-700,#374151))] overflow-hidden flex flex-col">
|
|
1492
|
+
<div class="flex-1 flex items-center justify-center p-4 bg-[color:var(--mcp-ui-surface-muted,var(--color-gray-50,#f9fafb))] dark:bg-[color:var(--mcp-ui-surface,var(--color-gray-900,#111827))] min-h-[200px]">
|
|
1493
1493
|
{/* The anchor only exists when the link URL passed `safeUrl` — a
|
|
1494
1494
|
`javascript:` link degrades to a plain, unlinked image. */}
|
|
1495
1495
|
<Show when={data().linkUrl} fallback={image()}>
|
|
@@ -1500,8 +1500,8 @@ function TextRenderer(props: { component: UIComponent }) {
|
|
|
1500
1500
|
)}
|
|
1501
1501
|
</Show>
|
|
1502
1502
|
</div>
|
|
1503
|
-
<div class="p-3 border-t border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800">
|
|
1504
|
-
<p class="text-sm text-gray-600 dark:text-gray-400 text-center italic">{data().credit}</p>
|
|
1503
|
+
<div class="p-3 border-t border-[color:var(--mcp-ui-border,var(--color-gray-200,#e5e7eb))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-700,#374151))] bg-[color:var(--mcp-ui-surface,var(--color-white,#fff))] dark:bg-[color:var(--mcp-ui-surface,var(--color-gray-800,#1f2937))]">
|
|
1504
|
+
<p class="text-sm text-[color:var(--mcp-ui-fg-muted,var(--color-gray-600,#4b5563))] dark:text-[color:var(--mcp-ui-fg-subtle,var(--color-gray-400,#9ca3af))] text-center italic">{data().credit}</p>
|
|
1505
1505
|
</div>
|
|
1506
1506
|
</div>
|
|
1507
1507
|
)
|
|
@@ -1522,10 +1522,10 @@ function IframeRenderer(props: { component: UIComponent }) {
|
|
|
1522
1522
|
// the `credentialless` decision.
|
|
1523
1523
|
const trustOptions = () => ({ customTrustedDomains: config.customTrustedIframeDomains })
|
|
1524
1524
|
return (
|
|
1525
|
-
<div class="w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden flex flex-col">
|
|
1525
|
+
<div class="w-full h-full bg-[color:var(--mcp-ui-surface,var(--color-white,#fff))] dark:bg-[color:var(--mcp-ui-surface,var(--color-gray-800,#1f2937))] rounded-lg shadow-[var(--mcp-ui-shadow,var(--shadow-sm))] border border-[color:var(--mcp-ui-border,var(--color-gray-200,#e5e7eb))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-700,#374151))] overflow-hidden flex flex-col">
|
|
1526
1526
|
<Show when={params.title}>
|
|
1527
|
-
<div class="px-4 py-2 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900">
|
|
1528
|
-
<h3 class="text-sm font-semibold text-gray-900 dark:text-white">{params.title}</h3>
|
|
1527
|
+
<div class="px-4 py-2 border-b border-[color:var(--mcp-ui-border,var(--color-gray-200,#e5e7eb))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-700,#374151))] bg-[color:var(--mcp-ui-surface-muted,var(--color-gray-50,#f9fafb))] dark:bg-[color:var(--mcp-ui-surface,var(--color-gray-900,#111827))]">
|
|
1528
|
+
<h3 class="text-sm font-semibold text-[color:var(--mcp-ui-fg,var(--color-gray-900,#111827))] dark:text-[color:var(--mcp-ui-fg,var(--color-white,#fff))]">{params.title}</h3>
|
|
1529
1529
|
</div>
|
|
1530
1530
|
</Show>
|
|
1531
1531
|
<iframe
|
|
@@ -1548,7 +1548,7 @@ function IframeRenderer(props: { component: UIComponent }) {
|
|
|
1548
1548
|
}
|
|
1549
1549
|
loading="lazy"
|
|
1550
1550
|
/>
|
|
1551
|
-
<IframeFallbackLink url={params.url} class="border-t border-gray-200 dark:border-gray-700" />
|
|
1551
|
+
<IframeFallbackLink url={params.url} class="border-t border-[color:var(--mcp-ui-border,var(--color-gray-200,#e5e7eb))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-700,#374151))]" />
|
|
1552
1552
|
</div>
|
|
1553
1553
|
)
|
|
1554
1554
|
}
|
|
@@ -1561,13 +1561,13 @@ function ImageRenderer(props: { component: UIComponent }) {
|
|
|
1561
1561
|
const params = props.component.params as any
|
|
1562
1562
|
|
|
1563
1563
|
return (
|
|
1564
|
-
<figure class={`w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden flex flex-col ${params.className || ''}`}>
|
|
1565
|
-
<div class="flex-1 flex items-center justify-center p-4 bg-gray-50 dark:bg-gray-900 min-h-[200px]">
|
|
1564
|
+
<figure class={`w-full h-full bg-[color:var(--mcp-ui-surface,var(--color-white,#fff))] dark:bg-[color:var(--mcp-ui-surface,var(--color-gray-800,#1f2937))] rounded-lg shadow-[var(--mcp-ui-shadow,var(--shadow-sm))] border border-[color:var(--mcp-ui-border,var(--color-gray-200,#e5e7eb))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-700,#374151))] overflow-hidden flex flex-col ${params.className || ''}`}>
|
|
1565
|
+
<div class="flex-1 flex items-center justify-center p-4 bg-[color:var(--mcp-ui-surface-muted,var(--color-gray-50,#f9fafb))] dark:bg-[color:var(--mcp-ui-surface,var(--color-gray-900,#111827))] min-h-[200px]">
|
|
1566
1566
|
<a
|
|
1567
1567
|
href={safeUrl(params.url)}
|
|
1568
1568
|
target="_blank"
|
|
1569
1569
|
rel="noopener noreferrer"
|
|
1570
|
-
class="cursor-zoom-in focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 rounded"
|
|
1570
|
+
class="cursor-zoom-in focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[color:var(--mcp-ui-focus,var(--color-blue-500))] rounded"
|
|
1571
1571
|
aria-label={formatMCPUIString(strings.imageViewFullSize, {
|
|
1572
1572
|
alt: params.alt || strings.imageAltFallback,
|
|
1573
1573
|
})}
|
|
@@ -1575,14 +1575,14 @@ function ImageRenderer(props: { component: UIComponent }) {
|
|
|
1575
1575
|
<img
|
|
1576
1576
|
src={safeUrl(params.url, { allowDataImage: true })}
|
|
1577
1577
|
alt={params.alt || strings.imageAlt}
|
|
1578
|
-
class="max-w-full max-h-[500px] object-contain rounded shadow-sm hover:opacity-95 transition-opacity"
|
|
1578
|
+
class="max-w-full max-h-[500px] object-contain rounded shadow-[var(--mcp-ui-shadow,var(--shadow-sm))] hover:opacity-95 transition-opacity"
|
|
1579
1579
|
loading="lazy"
|
|
1580
1580
|
/>
|
|
1581
1581
|
</a>
|
|
1582
1582
|
</div>
|
|
1583
1583
|
<Show when={params.caption}>
|
|
1584
|
-
<figcaption class="p-3 border-t border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800">
|
|
1585
|
-
<p class="text-sm text-gray-600 dark:text-gray-400 text-center">{params.caption}</p>
|
|
1584
|
+
<figcaption class="p-3 border-t border-[color:var(--mcp-ui-border,var(--color-gray-200,#e5e7eb))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-700,#374151))] bg-[color:var(--mcp-ui-surface,var(--color-white,#fff))] dark:bg-[color:var(--mcp-ui-surface,var(--color-gray-800,#1f2937))]">
|
|
1585
|
+
<p class="text-sm text-[color:var(--mcp-ui-fg-muted,var(--color-gray-600,#4b5563))] dark:text-[color:var(--mcp-ui-fg-subtle,var(--color-gray-400,#9ca3af))] text-center">{params.caption}</p>
|
|
1586
1586
|
</figcaption>
|
|
1587
1587
|
</Show>
|
|
1588
1588
|
</figure>
|
|
@@ -1605,10 +1605,10 @@ function LinkRenderer(props: { component: UIComponent }) {
|
|
|
1605
1605
|
label: params.label || strings.linkLabel,
|
|
1606
1606
|
description: params.description || params.url,
|
|
1607
1607
|
})}
|
|
1608
|
-
class={`flex items-center gap-3 p-4 bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors group h-full focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 ${params.className || ''}`}
|
|
1608
|
+
class={`flex items-center gap-3 p-4 bg-[color:var(--mcp-ui-surface,var(--color-white,#fff))] dark:bg-[color:var(--mcp-ui-surface,var(--color-gray-800,#1f2937))] rounded-lg shadow-[var(--mcp-ui-shadow,var(--shadow-sm))] border border-[color:var(--mcp-ui-border,var(--color-gray-200,#e5e7eb))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-700,#374151))] hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-50,#f9fafb))] dark:hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-700,#374151))] transition-colors group h-full focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[color:var(--mcp-ui-focus,var(--color-blue-500))] ${params.className || ''}`}
|
|
1609
1609
|
onClick={(e) => e.stopPropagation()}
|
|
1610
1610
|
>
|
|
1611
|
-
<div class="p-2 bg-blue-50 dark:bg-blue-900
|
|
1611
|
+
<div class="p-2 bg-[color:var(--mcp-ui-accent-soft,var(--color-blue-50))] dark:bg-[color:var(--mcp-ui-accent-soft,color-mix(in_oklab,var(--color-blue-900)_30%,transparent))] rounded-full text-[color:var(--mcp-ui-accent,var(--color-blue-600))] dark:text-[color:var(--mcp-ui-accent,var(--color-blue-400))] group-hover:bg-[color:var(--mcp-ui-accent-soft,var(--color-blue-100))] dark:group-hover:bg-[color:var(--mcp-ui-accent-soft,color-mix(in_oklab,var(--color-blue-900)_50%,transparent))] shrink-0 transition-colors" aria-hidden="true">
|
|
1612
1612
|
<svg
|
|
1613
1613
|
xmlns="http://www.w3.org/2000/svg"
|
|
1614
1614
|
class="w-5 h-5"
|
|
@@ -1624,16 +1624,16 @@ function LinkRenderer(props: { component: UIComponent }) {
|
|
|
1624
1624
|
</svg>
|
|
1625
1625
|
</div>
|
|
1626
1626
|
<div class="flex-1 min-w-0">
|
|
1627
|
-
<h4 class="text-sm font-medium text-gray-900 dark:text-white truncate group-hover:text-blue-600 dark:group-hover:text-blue-400 transition-colors">
|
|
1627
|
+
<h4 class="text-sm font-medium text-[color:var(--mcp-ui-fg,var(--color-gray-900,#111827))] dark:text-[color:var(--mcp-ui-fg,var(--color-white,#fff))] truncate group-hover:text-[color:var(--mcp-ui-accent,var(--color-blue-600))] dark:group-hover:text-[color:var(--mcp-ui-accent,var(--color-blue-400))] transition-colors">
|
|
1628
1628
|
{params.label || params.url}
|
|
1629
1629
|
</h4>
|
|
1630
1630
|
<Show when={params.description}>
|
|
1631
|
-
<p class="text-xs text-gray-500 dark:text-gray-400 truncate">{params.description}</p>
|
|
1631
|
+
<p class="text-xs text-[color:var(--mcp-ui-fg-muted,var(--color-gray-500,#6b7280))] dark:text-[color:var(--mcp-ui-fg-subtle,var(--color-gray-400,#9ca3af))] truncate">{params.description}</p>
|
|
1632
1632
|
</Show>
|
|
1633
1633
|
</div>
|
|
1634
1634
|
<svg
|
|
1635
1635
|
xmlns="http://www.w3.org/2000/svg"
|
|
1636
|
-
class="w-4 h-4 text-gray-400 group-hover:text-gray-600 dark:group-hover:text-gray-300 shrink-0 transition-colors"
|
|
1636
|
+
class="w-4 h-4 text-[color:var(--mcp-ui-fg-subtle,var(--color-gray-400,#9ca3af))] group-hover:text-[color:var(--mcp-ui-fg-muted,var(--color-gray-600,#4b5563))] dark:group-hover:text-[color:var(--mcp-ui-fg,var(--color-gray-300,#d1d5db))] shrink-0 transition-colors"
|
|
1637
1637
|
viewBox="0 0 24 24"
|
|
1638
1638
|
fill="none"
|
|
1639
1639
|
stroke="currentColor"
|
|
@@ -1758,7 +1758,7 @@ function ComponentRenderer(props: {
|
|
|
1758
1758
|
if (mode === 'inline-warn') {
|
|
1759
1759
|
return (
|
|
1760
1760
|
<div
|
|
1761
|
-
class="inline-flex items-center gap-1.5 px-2 py-1 rounded-md bg-yellow-50 dark:bg-yellow-900
|
|
1761
|
+
class="inline-flex items-center gap-1.5 px-2 py-1 rounded-md bg-[color:var(--mcp-ui-warning-soft,var(--color-yellow-50))] dark:bg-[color:var(--mcp-ui-warning-soft,color-mix(in_oklab,var(--color-yellow-900)_20%,transparent))] border border-[color:var(--mcp-ui-warning-border,var(--color-yellow-200))] dark:border-[color:var(--mcp-ui-warning-border,var(--color-yellow-800))] text-xs text-[color:var(--mcp-ui-warning,var(--color-yellow-800))] dark:text-[color:var(--mcp-ui-warning,var(--color-yellow-200))]"
|
|
1762
1762
|
role="alert"
|
|
1763
1763
|
aria-label={strings.validationWarning}
|
|
1764
1764
|
title={firstError}
|
|
@@ -1785,9 +1785,9 @@ function ComponentRenderer(props: {
|
|
|
1785
1785
|
|
|
1786
1786
|
// mode === 'block' (default, pre-v5.4.0 behavior)
|
|
1787
1787
|
return (
|
|
1788
|
-
<div class="w-full h-full bg-red-50 dark:bg-red-900
|
|
1789
|
-
<p class="text-sm font-medium text-red-900 dark:text-red-100">{strings.validationError}</p>
|
|
1790
|
-
<p class="text-xs text-red-700 dark:text-red-300 mt-1">
|
|
1788
|
+
<div class="w-full h-full bg-[color:var(--mcp-ui-danger-soft,var(--color-red-50))] dark:bg-[color:var(--mcp-ui-danger-soft,color-mix(in_oklab,var(--color-red-900)_20%,transparent))] border border-[color:var(--mcp-ui-danger-border,var(--color-red-200))] dark:border-[color:var(--mcp-ui-danger-border,var(--color-red-800))] rounded-lg p-4">
|
|
1789
|
+
<p class="text-sm font-medium text-[color:var(--mcp-ui-danger,var(--color-red-900))] dark:text-[color:var(--mcp-ui-danger,var(--color-red-100))]">{strings.validationError}</p>
|
|
1790
|
+
<p class="text-xs text-[color:var(--mcp-ui-danger,var(--color-red-700))] dark:text-[color:var(--mcp-ui-danger,var(--color-red-300))] mt-1">
|
|
1791
1791
|
{firstError}
|
|
1792
1792
|
</p>
|
|
1793
1793
|
</div>
|
|
@@ -1892,7 +1892,7 @@ function UnsupportedComponentFallback(props: { component: UIComponent }) {
|
|
|
1892
1892
|
return (
|
|
1893
1893
|
<div
|
|
1894
1894
|
role="alert"
|
|
1895
|
-
class="w-full rounded-lg border border-amber-300 bg-amber-50 px-3 py-2 text-sm text-amber-800 dark:border-amber-700
|
|
1895
|
+
class="w-full rounded-lg border border-[color:var(--mcp-ui-warning-border,var(--color-amber-300))] bg-[color:var(--mcp-ui-warning-soft,var(--color-amber-50))] px-3 py-2 text-sm text-[color:var(--mcp-ui-warning,var(--color-amber-800))] dark:border-[color:var(--mcp-ui-warning-border,color-mix(in_oklab,var(--color-amber-700)_50%,transparent))] dark:bg-[color:var(--mcp-ui-warning-soft,color-mix(in_oklab,var(--color-amber-900)_20%,transparent))] dark:text-[color:var(--mcp-ui-warning,var(--color-amber-200))]"
|
|
1896
1896
|
>
|
|
1897
1897
|
{strings.unsupportedComponentType} <code class="font-mono">{props.component.type}</code>
|
|
1898
1898
|
</div>
|
|
@@ -1956,10 +1956,10 @@ function ActionRenderer(props: { component: UIComponent }) {
|
|
|
1956
1956
|
target={safeUrl(params.url) ? '_blank' : undefined}
|
|
1957
1957
|
rel="noopener noreferrer"
|
|
1958
1958
|
aria-label={params.ariaLabel || params.label}
|
|
1959
|
-
class={`inline-flex items-center gap-2 px-4 py-2 rounded-md text-sm font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500
|
|
1960
|
-
${params.variant === 'primary' ? 'bg-blue-600 text-white hover:bg-blue-700' :
|
|
1961
|
-
params.variant === 'outline' ? 'border border-gray-300 text-gray-700 hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-800' :
|
|
1962
|
-
'text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300'}
|
|
1959
|
+
class={`inline-flex items-center gap-2 px-4 py-2 rounded-md text-sm font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[color:var(--mcp-ui-focus,var(--color-blue-500))]
|
|
1960
|
+
${params.variant === 'primary' ? 'bg-[color:var(--mcp-ui-accent,var(--color-blue-600))] text-[color:var(--mcp-ui-accent-fg,var(--color-white,#fff))] hover:bg-[color:var(--mcp-ui-accent-hover,var(--color-blue-700))]' :
|
|
1961
|
+
params.variant === 'outline' ? 'border border-[color:var(--mcp-ui-border,var(--color-gray-300,#d1d5db))] text-[color:var(--mcp-ui-fg,var(--color-gray-700,#374151))] hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-50,#f9fafb))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-600,#4b5563))] dark:text-[color:var(--mcp-ui-fg,var(--color-gray-300,#d1d5db))] dark:hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-800,#1f2937))]' :
|
|
1962
|
+
'text-[color:var(--mcp-ui-accent,var(--color-blue-600))] hover:text-[color:var(--mcp-ui-accent,var(--color-blue-800))] dark:text-[color:var(--mcp-ui-accent,var(--color-blue-400))] dark:hover:text-[color:var(--mcp-ui-accent,var(--color-blue-300))]'}
|
|
1963
1963
|
${params.className || ''}`}
|
|
1964
1964
|
onClick={handleClick}
|
|
1965
1965
|
>
|
|
@@ -1977,12 +1977,12 @@ function ActionRenderer(props: { component: UIComponent }) {
|
|
|
1977
1977
|
disabled={isDisabled()}
|
|
1978
1978
|
aria-busy={isExecuting() && isExecutable()}
|
|
1979
1979
|
aria-label={params.ariaLabel || params.label}
|
|
1980
|
-
class={`inline-flex items-center gap-2 px-4 py-2 rounded-md text-sm font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500
|
|
1981
|
-
${params.variant === 'primary' ? 'bg-blue-600 text-white hover:bg-blue-700 shadow-sm' :
|
|
1982
|
-
params.variant === 'secondary' ? 'bg-gray-100 text-gray-900 hover:bg-gray-200 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600' :
|
|
1983
|
-
params.variant === 'outline' ? 'border border-gray-300 text-gray-700 hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-800' :
|
|
1984
|
-
params.variant === 'danger' ? 'bg-red-600 text-white hover:bg-red-700' :
|
|
1985
|
-
'bg-transparent text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-800'}
|
|
1980
|
+
class={`inline-flex items-center gap-2 px-4 py-2 rounded-md text-sm font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[color:var(--mcp-ui-focus,var(--color-blue-500))]
|
|
1981
|
+
${params.variant === 'primary' ? 'bg-[color:var(--mcp-ui-accent,var(--color-blue-600))] text-[color:var(--mcp-ui-accent-fg,var(--color-white,#fff))] hover:bg-[color:var(--mcp-ui-accent-hover,var(--color-blue-700))] shadow-[var(--mcp-ui-shadow,var(--shadow-sm))]' :
|
|
1982
|
+
params.variant === 'secondary' ? 'bg-[color:var(--mcp-ui-surface-muted,var(--color-gray-100,#f3f4f6))] text-[color:var(--mcp-ui-fg,var(--color-gray-900,#111827))] hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-200,#e5e7eb))] dark:bg-[color:var(--mcp-ui-surface-muted,var(--color-gray-700,#374151))] dark:text-[color:var(--mcp-ui-fg,var(--color-white,#fff))] dark:hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-600,#4b5563))]' :
|
|
1983
|
+
params.variant === 'outline' ? 'border border-[color:var(--mcp-ui-border,var(--color-gray-300,#d1d5db))] text-[color:var(--mcp-ui-fg,var(--color-gray-700,#374151))] hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-50,#f9fafb))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-600,#4b5563))] dark:text-[color:var(--mcp-ui-fg,var(--color-gray-300,#d1d5db))] dark:hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-800,#1f2937))]' :
|
|
1984
|
+
params.variant === 'danger' ? 'bg-[color:var(--mcp-ui-danger,var(--color-red-600))] text-[color:var(--mcp-ui-accent-fg,var(--color-white,#fff))] hover:bg-[color:var(--mcp-ui-danger-hover,var(--color-red-700))]' :
|
|
1985
|
+
'bg-transparent text-[color:var(--mcp-ui-fg,var(--color-gray-700,#374151))] hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-100,#f3f4f6))] dark:text-[color:var(--mcp-ui-fg,var(--color-gray-300,#d1d5db))] dark:hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-800,#1f2937))]'}
|
|
1986
1986
|
${isDisabled() ? 'opacity-50 cursor-not-allowed' : ''}
|
|
1987
1987
|
${params.size === 'sm' ? 'px-3 py-1.5 text-xs' : params.size === 'lg' ? 'px-6 py-3 text-base' : ''}
|
|
1988
1988
|
${params.className || ''}`}
|
|
@@ -2017,32 +2017,32 @@ function ErrorCardRenderer(props: { error: any }) {
|
|
|
2017
2017
|
}
|
|
2018
2018
|
|
|
2019
2019
|
return (
|
|
2020
|
-
<div class="relative w-full bg-red-50 dark:bg-red-900
|
|
2020
|
+
<div class="relative w-full bg-[color:var(--mcp-ui-danger-soft,var(--color-red-50))] dark:bg-[color:var(--mcp-ui-danger-soft,color-mix(in_oklab,var(--color-red-900)_20%,transparent))] border border-[color:var(--mcp-ui-danger-border,var(--color-red-200))] dark:border-[color:var(--mcp-ui-danger-border,var(--color-red-800))] rounded-lg p-4 group">
|
|
2021
2021
|
<CopyButton getText={getErrorText} title={strings.copyErrorDetails} position="top-right" />
|
|
2022
2022
|
<div class="flex items-start gap-3">
|
|
2023
|
-
<div class="p-2 bg-red-100 dark:bg-red-900
|
|
2024
|
-
<svg class="w-5 h-5 text-red-600 dark:text-red-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
2023
|
+
<div class="p-2 bg-[color:var(--mcp-ui-danger-soft,var(--color-red-100))] dark:bg-[color:var(--mcp-ui-danger-soft,color-mix(in_oklab,var(--color-red-900)_40%,transparent))] rounded-full shrink-0">
|
|
2024
|
+
<svg class="w-5 h-5 text-[color:var(--mcp-ui-danger,var(--color-red-600))] dark:text-[color:var(--mcp-ui-danger,var(--color-red-400))]" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
2025
2025
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
|
|
2026
2026
|
</svg>
|
|
2027
2027
|
</div>
|
|
2028
2028
|
<div class="flex-1 min-w-0">
|
|
2029
|
-
<h4 class="text-sm font-semibold text-red-800 dark:text-red-200">
|
|
2029
|
+
<h4 class="text-sm font-semibold text-[color:var(--mcp-ui-danger,var(--color-red-800))] dark:text-[color:var(--mcp-ui-danger,var(--color-red-200))]">
|
|
2030
2030
|
{formatMCPUIString(strings.toolErrorTitle, {
|
|
2031
2031
|
tool: props.error.tool || strings.errorUnknownToolName,
|
|
2032
2032
|
})}
|
|
2033
2033
|
</h4>
|
|
2034
|
-
<p class="text-sm text-red-700 dark:text-red-300 mt-1">
|
|
2034
|
+
<p class="text-sm text-[color:var(--mcp-ui-danger,var(--color-red-700))] dark:text-[color:var(--mcp-ui-danger,var(--color-red-300))] mt-1">
|
|
2035
2035
|
{props.error.message || strings.errorToolExecution}
|
|
2036
2036
|
</p>
|
|
2037
2037
|
<Show when={props.error.type}>
|
|
2038
|
-
<p class="text-xs text-red-600 dark:text-red-400 mt-1">
|
|
2038
|
+
<p class="text-xs text-[color:var(--mcp-ui-danger,var(--color-red-600))] dark:text-[color:var(--mcp-ui-danger,var(--color-red-400))] mt-1">
|
|
2039
2039
|
{formatMCPUIString(strings.errorTypeLabel, { type: props.error.type })}
|
|
2040
2040
|
</p>
|
|
2041
2041
|
</Show>
|
|
2042
2042
|
<Show when={props.error.suggestions?.length}>
|
|
2043
2043
|
<div class="mt-3">
|
|
2044
|
-
<p class="text-xs font-medium text-red-700 dark:text-red-300">{strings.errorSuggestions}</p>
|
|
2045
|
-
<ul class="mt-1 text-xs text-red-600 dark:text-red-400 list-disc list-inside">
|
|
2044
|
+
<p class="text-xs font-medium text-[color:var(--mcp-ui-danger,var(--color-red-700))] dark:text-[color:var(--mcp-ui-danger,var(--color-red-300))]">{strings.errorSuggestions}</p>
|
|
2045
|
+
<ul class="mt-1 text-xs text-[color:var(--mcp-ui-danger,var(--color-red-600))] dark:text-[color:var(--mcp-ui-danger,var(--color-red-400))] list-disc list-inside">
|
|
2046
2046
|
<For each={props.error.suggestions}>
|
|
2047
2047
|
{(suggestion: string) => <li>{suggestion}</li>}
|
|
2048
2048
|
</For>
|
|
@@ -2050,7 +2050,7 @@ function ErrorCardRenderer(props: { error: any }) {
|
|
|
2050
2050
|
</div>
|
|
2051
2051
|
</Show>
|
|
2052
2052
|
<Show when={mounted() && props.error.timestamp}>
|
|
2053
|
-
<p class="text-xs text-red-500 dark:text-red-500 mt-2">
|
|
2053
|
+
<p class="text-xs text-[color:var(--mcp-ui-danger,var(--color-red-500))] dark:text-[color:var(--mcp-ui-danger,var(--color-red-500))] mt-2">
|
|
2054
2054
|
{new Date(props.error.timestamp).toLocaleString(strings.locale)}
|
|
2055
2055
|
</p>
|
|
2056
2056
|
</Show>
|
|
@@ -2097,10 +2097,10 @@ function UIResourceHtmlRenderer(props: { resource: any }) {
|
|
|
2097
2097
|
}
|
|
2098
2098
|
|
|
2099
2099
|
return (
|
|
2100
|
-
<div class="w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden">
|
|
2100
|
+
<div class="w-full bg-[color:var(--mcp-ui-surface,var(--color-white,#fff))] dark:bg-[color:var(--mcp-ui-surface,var(--color-gray-800,#1f2937))] rounded-lg shadow-[var(--mcp-ui-shadow,var(--shadow-sm))] border border-[color:var(--mcp-ui-border,var(--color-gray-200,#e5e7eb))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-700,#374151))] overflow-hidden">
|
|
2101
2101
|
<Show when={props.resource.metadata?.title || props.resource.uri}>
|
|
2102
|
-
<div class="px-4 py-2 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900">
|
|
2103
|
-
<h3 class="text-sm font-semibold text-gray-900 dark:text-white capitalize">
|
|
2102
|
+
<div class="px-4 py-2 border-b border-[color:var(--mcp-ui-border,var(--color-gray-200,#e5e7eb))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-700,#374151))] bg-[color:var(--mcp-ui-surface-muted,var(--color-gray-50,#f9fafb))] dark:bg-[color:var(--mcp-ui-surface,var(--color-gray-900,#111827))]">
|
|
2103
|
+
<h3 class="text-sm font-semibold text-[color:var(--mcp-ui-fg,var(--color-gray-900,#111827))] dark:text-[color:var(--mcp-ui-fg,var(--color-white,#fff))] capitalize">
|
|
2104
2104
|
{resourceTitle()}
|
|
2105
2105
|
</h3>
|
|
2106
2106
|
</div>
|
|
@@ -2231,7 +2231,7 @@ export const UIResourceRenderer: Component<UIResourceRendererProps> = (props) =>
|
|
|
2231
2231
|
return (
|
|
2232
2232
|
<RenderProvider renderComponent={renderComponent}>
|
|
2233
2233
|
<div
|
|
2234
|
-
class={`w-full ${props.class || ''}`}
|
|
2234
|
+
class={`mcp-ui-root [background-color:var(--mcp-ui-bg)] w-full ${props.class || ''}`}
|
|
2235
2235
|
{...(isLayoutContent
|
|
2236
2236
|
? { 'data-mcp-ui-layout-id': outerKey() }
|
|
2237
2237
|
: { 'data-mcp-ui-component-id': outerKey() })}
|