@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.
Files changed (124) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/README.md +47 -0
  3. package/dist/components/ActionGroupRenderer.cjs +6 -6
  4. package/dist/components/ActionGroupRenderer.cjs.map +1 -1
  5. package/dist/components/ActionGroupRenderer.js +6 -6
  6. package/dist/components/ActionGroupRenderer.js.map +1 -1
  7. package/dist/components/AutocompleteDropdown.cjs +6 -6
  8. package/dist/components/AutocompleteDropdown.cjs.map +1 -1
  9. package/dist/components/AutocompleteDropdown.js +6 -6
  10. package/dist/components/AutocompleteDropdown.js.map +1 -1
  11. package/dist/components/AutocompleteFormField.cjs +6 -5
  12. package/dist/components/AutocompleteFormField.cjs.map +1 -1
  13. package/dist/components/AutocompleteFormField.d.ts.map +1 -1
  14. package/dist/components/AutocompleteFormField.js +6 -5
  15. package/dist/components/AutocompleteFormField.js.map +1 -1
  16. package/dist/components/ChartJSRenderer.cjs +216 -6
  17. package/dist/components/ChartJSRenderer.cjs.map +1 -1
  18. package/dist/components/ChartJSRenderer.d.ts.map +1 -1
  19. package/dist/components/ChartJSRenderer.js +217 -7
  20. package/dist/components/ChartJSRenderer.js.map +1 -1
  21. package/dist/components/ChatPrompt.cjs +5 -5
  22. package/dist/components/ChatPrompt.cjs.map +1 -1
  23. package/dist/components/ChatPrompt.js +5 -5
  24. package/dist/components/ChatPrompt.js.map +1 -1
  25. package/dist/components/ComponentToolbar.cjs +5 -5
  26. package/dist/components/ComponentToolbar.cjs.map +1 -1
  27. package/dist/components/ComponentToolbar.js +5 -5
  28. package/dist/components/ComponentToolbar.js.map +1 -1
  29. package/dist/components/DegradedFallback.cjs +1 -1
  30. package/dist/components/DegradedFallback.cjs.map +1 -1
  31. package/dist/components/DegradedFallback.js +1 -1
  32. package/dist/components/DegradedFallback.js.map +1 -1
  33. package/dist/components/ExpandableWrapper.cjs +10 -7
  34. package/dist/components/ExpandableWrapper.cjs.map +1 -1
  35. package/dist/components/ExpandableWrapper.d.ts.map +1 -1
  36. package/dist/components/ExpandableWrapper.js +10 -7
  37. package/dist/components/ExpandableWrapper.js.map +1 -1
  38. package/dist/components/FormFieldRenderer.cjs +13 -12
  39. package/dist/components/FormFieldRenderer.cjs.map +1 -1
  40. package/dist/components/FormFieldRenderer.d.ts.map +1 -1
  41. package/dist/components/FormFieldRenderer.js +13 -12
  42. package/dist/components/FormFieldRenderer.js.map +1 -1
  43. package/dist/components/FormRenderer.cjs +1 -1
  44. package/dist/components/FormRenderer.cjs.map +1 -1
  45. package/dist/components/FormRenderer.js +1 -1
  46. package/dist/components/FormRenderer.js.map +1 -1
  47. package/dist/components/GenerativeUIErrorBoundary.cjs +1 -1
  48. package/dist/components/GenerativeUIErrorBoundary.cjs.map +1 -1
  49. package/dist/components/GenerativeUIErrorBoundary.js +1 -1
  50. package/dist/components/GenerativeUIErrorBoundary.js.map +1 -1
  51. package/dist/components/GhostText.cjs +2 -2
  52. package/dist/components/GhostText.cjs.map +1 -1
  53. package/dist/components/GhostText.js +2 -2
  54. package/dist/components/GhostText.js.map +1 -1
  55. package/dist/components/GraphRenderer.cjs +100 -29
  56. package/dist/components/GraphRenderer.cjs.map +1 -1
  57. package/dist/components/GraphRenderer.d.ts +1 -1
  58. package/dist/components/GraphRenderer.d.ts.map +1 -1
  59. package/dist/components/GraphRenderer.js +100 -29
  60. package/dist/components/GraphRenderer.js.map +1 -1
  61. package/dist/components/MissingValue.cjs +2 -2
  62. package/dist/components/MissingValue.cjs.map +1 -1
  63. package/dist/components/MissingValue.js +2 -2
  64. package/dist/components/MissingValue.js.map +1 -1
  65. package/dist/components/ModalRenderer.cjs +39 -31
  66. package/dist/components/ModalRenderer.cjs.map +1 -1
  67. package/dist/components/ModalRenderer.d.ts.map +1 -1
  68. package/dist/components/ModalRenderer.js +40 -32
  69. package/dist/components/ModalRenderer.js.map +1 -1
  70. package/dist/components/PortalDropdownMenu.cjs +6 -3
  71. package/dist/components/PortalDropdownMenu.cjs.map +1 -1
  72. package/dist/components/PortalDropdownMenu.d.ts.map +1 -1
  73. package/dist/components/PortalDropdownMenu.js +7 -4
  74. package/dist/components/PortalDropdownMenu.js.map +1 -1
  75. package/dist/components/ScratchpadPanel.cjs +38 -44
  76. package/dist/components/ScratchpadPanel.cjs.map +1 -1
  77. package/dist/components/ScratchpadPanel.d.ts.map +1 -1
  78. package/dist/components/ScratchpadPanel.js +38 -44
  79. package/dist/components/ScratchpadPanel.js.map +1 -1
  80. package/dist/components/UIResourceRenderer.cjs +20 -20
  81. package/dist/components/UIResourceRenderer.cjs.map +1 -1
  82. package/dist/components/UIResourceRenderer.js +20 -20
  83. package/dist/components/UIResourceRenderer.js.map +1 -1
  84. package/dist/components/chart-missing-plugin.cjs +4 -4
  85. package/dist/components/chart-missing-plugin.cjs.map +1 -1
  86. package/dist/components/chart-missing-plugin.d.ts +3 -1
  87. package/dist/components/chart-missing-plugin.d.ts.map +1 -1
  88. package/dist/components/chart-missing-plugin.js +4 -4
  89. package/dist/components/chart-missing-plugin.js.map +1 -1
  90. package/dist/utils/math-markdown.cjs +1 -1
  91. package/dist/utils/math-markdown.cjs.map +1 -1
  92. package/dist/utils/math-markdown.js +1 -1
  93. package/dist/utils/math-markdown.js.map +1 -1
  94. package/dist/utils/theme.cjs +91 -0
  95. package/dist/utils/theme.cjs.map +1 -0
  96. package/dist/utils/theme.d.ts +11 -0
  97. package/dist/utils/theme.d.ts.map +1 -0
  98. package/dist/utils/theme.js +91 -0
  99. package/dist/utils/theme.js.map +1 -0
  100. package/docs/SECURITY-DEPENDENCIES.md +81 -0
  101. package/docs/THEMING.md +205 -0
  102. package/package.json +5 -3
  103. package/src/components/ActionGroupRenderer.tsx +6 -6
  104. package/src/components/AutocompleteDropdown.tsx +17 -17
  105. package/src/components/AutocompleteFormField.tsx +10 -9
  106. package/src/components/ChartJSRenderer.tsx +483 -239
  107. package/src/components/ChatPrompt.tsx +16 -16
  108. package/src/components/ComponentToolbar.tsx +5 -5
  109. package/src/components/DegradedFallback.tsx +9 -9
  110. package/src/components/ExpandableWrapper.tsx +15 -11
  111. package/src/components/FormFieldRenderer.tsx +52 -51
  112. package/src/components/FormRenderer.tsx +12 -12
  113. package/src/components/GenerativeUIErrorBoundary.tsx +6 -6
  114. package/src/components/GhostText.tsx +7 -7
  115. package/src/components/GraphRenderer.tsx +83 -67
  116. package/src/components/MissingValue.tsx +2 -2
  117. package/src/components/ModalRenderer.tsx +11 -5
  118. package/src/components/PortalDropdownMenu.tsx +6 -2
  119. package/src/components/ScratchpadPanel.tsx +144 -141
  120. package/src/components/UIResourceRenderer.tsx +101 -101
  121. package/src/components/chart-missing-plugin.ts +5 -3
  122. package/src/styles/autocomplete.css +53 -53
  123. package/src/utils/math-markdown.ts +1 -1
  124. package/src/utils/theme.ts +101 -0
package/CHANGELOG.md CHANGED
@@ -5,6 +5,48 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [6.25.1] - 2026-10-18
9
+
10
+ ### Security
11
+
12
+ - Raise the published DOMPurify floor to `^3.4.17` (lockfile: 3.4.17), covering
13
+ both reported `IN_PLACE` advisories and subsequent upstream hardening. The
14
+ library's existing string-based sanitization profiles remain unchanged.
15
+ - Update workspace Solid to 1.9.17 and Seroval/Seroval plugins to 1.6.11,
16
+ using Solid's supported 1.6.x dependency range instead of the stale 1.5.x
17
+ override. Add real asynchronous SSR and JSON serialization compatibility tests.
18
+ - Update build/test resolutions to `source-map-js` 1.2.2 and `brace-expansion`
19
+ 5.0.12. Audit falls from nine advisories to one remaining HIGH advisory in
20
+ the distinct, unpatched development dependency `braces` 3.0.3. No audit ignore
21
+ or advisory dismissal is added; see `docs/SECURITY-DEPENDENCIES.md`.
22
+ - Workspace overrides do not propagate to consuming applications. Hosts must
23
+ separately update their Solid/Seroval lockfiles; the public Solid peer range
24
+ and component APIs are unchanged.
25
+
26
+ ## [6.25.0] - 2026-10-18
27
+
28
+ ### Added
29
+
30
+ - Inherited `--mcp-ui-*` CSS theme tokens with per-use original color fallbacks
31
+ for prompts, resource/table chrome, scratchpads, form controls, autocomplete,
32
+ expanded dialogs, export menus and chart/graph chrome. No required provider,
33
+ new dependency, global root defaults or component prop changes.
34
+ - Body portal theme synchronization, including local `.dark`, live ancestor
35
+ token changes and removal; fullscreen content retains its original DOM.
36
+ - Scoped Chart.js/G6 series, grid, axis, label and tooltip tokens with live
37
+ updates and explicit caller color precedence; original engine defaults are
38
+ retained when no host tokens are supplied.
39
+ - Frozen 6.24.0 Chromium computed-style comparisons, host/portal regressions,
40
+ static Tailwind class checks and theming documentation with coverage limits.
41
+
42
+ ### Fixed
43
+
44
+ - Form input and autocomplete text respects the host foreground without a
45
+ `.dark` class, preserving inherited default colors and muted field states.
46
+ - Explicit point paints no longer block themed line/radar strokes. Live
47
+ Chart.js theme updates also refresh resolved shared point/bar colors without
48
+ replacing their options or changing caller-provided non-color settings.
49
+
8
50
  ## [6.24.0] - 2026-10-03
9
51
 
10
52
  Explicit missing values in charts and tables, and a unit per chart — lot 1 of
package/README.md CHANGED
@@ -5,6 +5,53 @@ SolidJS components + chat toolkit for MCP-generated UI. Part of the [MCP UI ecos
5
5
  [![npm version](https://img.shields.io/npm/v/@seed-ship/mcp-ui-solid.svg)](https://www.npmjs.com/package/@seed-ship/mcp-ui-solid)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
7
 
8
+ ## What's New in v6.25.1
9
+
10
+ DOMPurify now requires `^3.4.17`. The workspace uses the compatible Solid
11
+ 1.9.17 patch with corrected Seroval and build-tool dependency resolutions,
12
+ covered by a real server-rendering/serialization smoke test. These workspace
13
+ overrides do not update an application's own Solid/Seroval lockfile.
14
+ See [security dependency notes](./docs/SECURITY-DEPENDENCIES.md) for host
15
+ upgrade guidance and the remaining unpatched development-tooling advisory.
16
+
17
+ ## What's New in v6.25.0
18
+
19
+ Inherited `--mcp-ui-*` CSS tokens theme prompts, resource/table chrome,
20
+ scratchpads, form controls, autocomplete and chart/graph chrome. Body portals
21
+ follow their local host theme; mounted Chart.js/G6 instances update without
22
+ losing their identity. Existing colors remain the defaults.
23
+
24
+ ## Theming
25
+
26
+ Set variables on an ancestor; no provider or extra stylesheet is required
27
+ for the Tailwind-based components. Keep scanning this package's `src/**/*.{ts,tsx}`
28
+ with Tailwind v4 and your existing class-based `.dark` variant.
29
+
30
+ ```css
31
+ .app-theme {
32
+ --mcp-ui-surface: #ffffff;
33
+ --mcp-ui-surface-muted: #f1f5f9;
34
+ --mcp-ui-fg: #0f172a;
35
+ --mcp-ui-fg-muted: #475569;
36
+ --mcp-ui-border: #cbd5e1;
37
+ --mcp-ui-accent: #1d4ed8;
38
+ }
39
+ .dark .app-theme {
40
+ --mcp-ui-surface: #0f172a;
41
+ --mcp-ui-surface-muted: #1e293b;
42
+ --mcp-ui-fg: #f8fafc;
43
+ --mcp-ui-fg-muted: #cbd5e1;
44
+ --mcp-ui-border: #64748b;
45
+ --mcp-ui-accent: #93c5fd;
46
+ }
47
+ ```
48
+
49
+ The library deliberately does not redeclare public tokens on nested roots:
50
+ an ancestor's tokens keep inheriting. Each use falls back to its original
51
+ color, preserving the existing light/dark distinctions. Optional autocomplete
52
+ CSS is still imported as before. See [the complete token reference, portal
53
+ behavior, contrast limits and migration coverage](./docs/THEMING.md).
54
+
8
55
  ## What's New in v6.24.0
9
56
 
10
57
  Explicit missing values in charts and tables, and a `unit` per chart. A `null`
@@ -33,17 +33,17 @@ const ActionButton = (props) => {
33
33
  const variantClass = () => {
34
34
  switch (props.action.variant) {
35
35
  case "primary":
36
- return "bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500";
36
+ return "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))] focus:ring-[color:var(--mcp-ui-focus,var(--color-blue-500))]";
37
37
  case "secondary":
38
- return "bg-gray-200 text-gray-800 hover:bg-gray-300 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600 focus:ring-gray-500";
38
+ return "bg-[color:var(--mcp-ui-surface-muted,var(--color-gray-200,#e5e7eb))] text-[color:var(--mcp-ui-fg,var(--color-gray-800,#1f2937))] hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-300,#d1d5db))] 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))] focus:ring-[color:var(--mcp-ui-focus,var(--color-gray-500,#6b7280))]";
39
39
  case "outline":
40
- return "border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 focus:ring-gray-500";
40
+ return "border border-[color:var(--mcp-ui-border,var(--color-gray-300,#d1d5db))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-600,#4b5563))] text-[color:var(--mcp-ui-fg,var(--color-gray-700,#374151))] dark:text-[color:var(--mcp-ui-fg,var(--color-gray-300,#d1d5db))] 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))] focus:ring-[color:var(--mcp-ui-focus,var(--color-gray-500,#6b7280))]";
41
41
  case "ghost":
42
- return "text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 focus:ring-gray-500";
42
+ return "text-[color:var(--mcp-ui-fg,var(--color-gray-700,#374151))] dark:text-[color:var(--mcp-ui-fg,var(--color-gray-300,#d1d5db))] 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))] focus:ring-[color:var(--mcp-ui-focus,var(--color-gray-500,#6b7280))]";
43
43
  case "danger":
44
- return "bg-red-600 text-white hover:bg-red-700 focus:ring-red-500";
44
+ return "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))] focus:ring-[color:var(--mcp-ui-focus,var(--color-red-500))]";
45
45
  default:
46
- return "bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500";
46
+ return "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))] focus:ring-[color:var(--mcp-ui-focus,var(--color-blue-500))]";
47
47
  }
48
48
  };
49
49
  const sizeClass = () => {
@@ -1 +1 @@
1
- {"version":3,"file":"ActionGroupRenderer.cjs","sources":["../../src/components/ActionGroupRenderer.tsx"],"sourcesContent":["/**\n * ActionGroupRenderer - Group of actions with layout options\n * Sprint 3: UX Improvements\n */\n\nimport { Component, For, Show } from 'solid-js'\nimport type { UIComponent, ActionGroupParams, ActionComponentParams } from '../types'\nimport { useAction } from '../hooks/useAction'\nimport { safeUrl } from '../utils/safe-url'\nimport { useMCPUIStrings } from '../context/MCPUIStringsContext'\n\nexport interface ActionGroupRendererProps {\n /**\n * UIComponent with action-group params (for declarative use)\n */\n component?: UIComponent\n\n /**\n * Direct action group params (alternative to component)\n */\n params?: ActionGroupParams\n}\n\n/**\n * Render a single action button with variants and click handling\n */\nconst ActionButton: Component<{\n action: ActionComponentParams\n index: number\n}> = (props) => {\n const { execute, executeAction, isExecuting } = useAction()\n\n // tool-call and submit both go through the host executor — they show a\n // loading state and gate disabled while running. link does neither.\n const isExecutable = () =>\n props.action.action === 'tool-call' || props.action.action === 'submit'\n\n const handleClick = async (e: MouseEvent) => {\n if (props.action.disabled) return\n\n if (props.action.action === 'tool-call' && props.action.toolName) {\n e.preventDefault()\n await execute(props.action.toolName, props.action.params || {})\n } else if (props.action.action === 'submit') {\n // submit is NOT a tool call — route it through the executor with the\n // `action: 'submit'` kind preserved so the host can POST to\n // params.submit_url etc. Works without a surrounding <form>.\n e.preventDefault()\n await executeAction({\n action: 'submit',\n toolName: props.action.toolName || 'submit',\n params: props.action.params || {},\n })\n } else if (props.action.action === 'link' && props.action.url) {\n window.open(props.action.url, '_blank', 'noopener,noreferrer')\n }\n }\n\n const isDisabled = () =>\n props.action.disabled || (isExecutable() && isExecuting())\n\n const variantClass = () => {\n switch (props.action.variant) {\n case 'primary':\n return 'bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500'\n case 'secondary':\n return 'bg-gray-200 text-gray-800 hover:bg-gray-300 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600 focus:ring-gray-500'\n case 'outline':\n return 'border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 focus:ring-gray-500'\n case 'ghost':\n return 'text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 focus:ring-gray-500'\n case 'danger':\n return 'bg-red-600 text-white hover:bg-red-700 focus:ring-red-500'\n default:\n return 'bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500'\n }\n }\n\n const sizeClass = () => {\n switch (props.action.size) {\n case 'sm':\n return 'px-2 py-1 text-xs'\n case 'lg':\n return 'px-6 py-3 text-base'\n default:\n return 'px-4 py-2 text-sm'\n }\n }\n\n // Render as link if it's a link action\n if (props.action.type === 'link' || (props.action.action === 'link' && props.action.url)) {\n return (\n <a\n href={safeUrl(props.action.url ?? '') ?? '#'}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class={`inline-flex items-center justify-center gap-2 rounded-md font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 ${variantClass()} ${sizeClass()} ${\n isDisabled() ? 'opacity-50 cursor-not-allowed pointer-events-none' : ''\n }`}\n >\n <Show when={props.action.icon}>\n <span class=\"text-current\">{props.action.icon}</span>\n </Show>\n {props.action.label}\n </a>\n )\n }\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={isDisabled()}\n class={`inline-flex items-center justify-center gap-2 rounded-md font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 ${variantClass()} ${sizeClass()} ${\n isDisabled() ? 'opacity-50 cursor-not-allowed' : ''\n }`}\n >\n <Show when={isExecuting() && isExecutable()}>\n <span class=\"animate-spin h-4 w-4 border-2 border-current border-t-transparent rounded-full\" />\n </Show>\n <Show when={props.action.icon && !(isExecuting() && isExecutable())}>\n <span class=\"text-current\">{props.action.icon}</span>\n </Show>\n {props.action.label}\n </button>\n )\n}\n\n/**\n * Action group component for rendering multiple actions with consistent layout\n *\n * @example\n * ```tsx\n * const actionGroup: UIComponent = {\n * id: 'form-actions',\n * type: 'action-group',\n * position: { colStart: 1, colSpan: 12 },\n * params: {\n * layout: 'end',\n * gap: 'md',\n * actions: [\n * { label: 'Cancel', variant: 'outline', action: 'link', url: '/back' },\n * { label: 'Save', variant: 'primary', action: 'tool-call', toolName: 'save' },\n * ],\n * },\n * }\n * <ActionGroupRenderer component={actionGroup} />\n * ```\n */\nexport const ActionGroupRenderer: Component<ActionGroupRendererProps> = (props) => {\n const strings = useMCPUIStrings()\n const params = () => props.params || (props.component?.params as ActionGroupParams) || { actions: [] }\n\n const layoutClass = () => {\n switch (params()?.layout) {\n case 'vertical':\n return 'flex flex-col'\n case 'space-between':\n return 'flex justify-between'\n case 'end':\n return 'flex justify-end'\n case 'center':\n return 'flex justify-center'\n default: // horizontal\n return 'flex'\n }\n }\n\n const gapClass = () => {\n switch (params()?.gap) {\n case 'none':\n return 'gap-0'\n case 'sm':\n return 'gap-1'\n case 'lg':\n return 'gap-4'\n default: // md\n return 'gap-2'\n }\n }\n\n return (\n <div\n class={`${layoutClass()} ${gapClass()} ${params()?.fullWidth ? 'w-full' : ''}`}\n role=\"group\"\n aria-label={params()?.label || strings.actionGroupLabel}\n >\n <For each={params()?.actions || []}>\n {(action, index) => <ActionButton action={action} index={index()} />}\n </For>\n </div>\n )\n}\n"],"names":["ActionButton","props","execute","executeAction","isExecuting","useAction","isExecutable","action","handleClick","e","disabled","toolName","preventDefault","params","url","window","open","isDisabled","variantClass","variant","sizeClass","size","type","_el$","_$getNextElement","_tmpl$2","_el$3","firstChild","_el$4","_co$","_$getNextMarker","nextSibling","_el$5","_el$6","_co$2","_$insert","_$createComponent","Show","when","icon","children","_el$2","_tmpl$","label","_$effect","_p$","_v$","safeUrl","_v$2","_$setAttribute","t","_$className","undefined","_el$7","_tmpl$4","_el$0","_el$1","_co$3","_el$10","_el$11","_co$4","_el$12","_el$13","_co$5","$$click","_$memo","_tmpl$3","_el$9","_v$3","_v$4","_$setProperty","_$runHydrationEvents","ActionGroupRenderer","strings","useMCPUIStrings","component","actions","layoutClass","layout","gapClass","gap","_el$14","_tmpl$5","For","each","index","_v$5","fullWidth","_v$6","actionGroupLabel","_$delegateEvents"],"mappings":"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"}
1
+ {"version":3,"file":"ActionGroupRenderer.cjs","sources":["../../src/components/ActionGroupRenderer.tsx"],"sourcesContent":["/**\n * ActionGroupRenderer - Group of actions with layout options\n * Sprint 3: UX Improvements\n */\n\nimport { Component, For, Show } from 'solid-js'\nimport type { UIComponent, ActionGroupParams, ActionComponentParams } from '../types'\nimport { useAction } from '../hooks/useAction'\nimport { safeUrl } from '../utils/safe-url'\nimport { useMCPUIStrings } from '../context/MCPUIStringsContext'\n\nexport interface ActionGroupRendererProps {\n /**\n * UIComponent with action-group params (for declarative use)\n */\n component?: UIComponent\n\n /**\n * Direct action group params (alternative to component)\n */\n params?: ActionGroupParams\n}\n\n/**\n * Render a single action button with variants and click handling\n */\nconst ActionButton: Component<{\n action: ActionComponentParams\n index: number\n}> = (props) => {\n const { execute, executeAction, isExecuting } = useAction()\n\n // tool-call and submit both go through the host executor — they show a\n // loading state and gate disabled while running. link does neither.\n const isExecutable = () =>\n props.action.action === 'tool-call' || props.action.action === 'submit'\n\n const handleClick = async (e: MouseEvent) => {\n if (props.action.disabled) return\n\n if (props.action.action === 'tool-call' && props.action.toolName) {\n e.preventDefault()\n await execute(props.action.toolName, props.action.params || {})\n } else if (props.action.action === 'submit') {\n // submit is NOT a tool call — route it through the executor with the\n // `action: 'submit'` kind preserved so the host can POST to\n // params.submit_url etc. Works without a surrounding <form>.\n e.preventDefault()\n await executeAction({\n action: 'submit',\n toolName: props.action.toolName || 'submit',\n params: props.action.params || {},\n })\n } else if (props.action.action === 'link' && props.action.url) {\n window.open(props.action.url, '_blank', 'noopener,noreferrer')\n }\n }\n\n const isDisabled = () =>\n props.action.disabled || (isExecutable() && isExecuting())\n\n const variantClass = () => {\n switch (props.action.variant) {\n case 'primary':\n return '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))] focus:ring-[color:var(--mcp-ui-focus,var(--color-blue-500))]'\n case 'secondary':\n return 'bg-[color:var(--mcp-ui-surface-muted,var(--color-gray-200,#e5e7eb))] text-[color:var(--mcp-ui-fg,var(--color-gray-800,#1f2937))] hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-300,#d1d5db))] 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))] focus:ring-[color:var(--mcp-ui-focus,var(--color-gray-500,#6b7280))]'\n case 'outline':\n return 'border border-[color:var(--mcp-ui-border,var(--color-gray-300,#d1d5db))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-600,#4b5563))] text-[color:var(--mcp-ui-fg,var(--color-gray-700,#374151))] dark:text-[color:var(--mcp-ui-fg,var(--color-gray-300,#d1d5db))] 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))] focus:ring-[color:var(--mcp-ui-focus,var(--color-gray-500,#6b7280))]'\n case 'ghost':\n return 'text-[color:var(--mcp-ui-fg,var(--color-gray-700,#374151))] dark:text-[color:var(--mcp-ui-fg,var(--color-gray-300,#d1d5db))] 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))] focus:ring-[color:var(--mcp-ui-focus,var(--color-gray-500,#6b7280))]'\n case 'danger':\n return '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))] focus:ring-[color:var(--mcp-ui-focus,var(--color-red-500))]'\n default:\n return '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))] focus:ring-[color:var(--mcp-ui-focus,var(--color-blue-500))]'\n }\n }\n\n const sizeClass = () => {\n switch (props.action.size) {\n case 'sm':\n return 'px-2 py-1 text-xs'\n case 'lg':\n return 'px-6 py-3 text-base'\n default:\n return 'px-4 py-2 text-sm'\n }\n }\n\n // Render as link if it's a link action\n if (props.action.type === 'link' || (props.action.action === 'link' && props.action.url)) {\n return (\n <a\n href={safeUrl(props.action.url ?? '') ?? '#'}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class={`inline-flex items-center justify-center gap-2 rounded-md font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 ${variantClass()} ${sizeClass()} ${\n isDisabled() ? 'opacity-50 cursor-not-allowed pointer-events-none' : ''\n }`}\n >\n <Show when={props.action.icon}>\n <span class=\"text-current\">{props.action.icon}</span>\n </Show>\n {props.action.label}\n </a>\n )\n }\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={isDisabled()}\n class={`inline-flex items-center justify-center gap-2 rounded-md font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 ${variantClass()} ${sizeClass()} ${\n isDisabled() ? 'opacity-50 cursor-not-allowed' : ''\n }`}\n >\n <Show when={isExecuting() && isExecutable()}>\n <span class=\"animate-spin h-4 w-4 border-2 border-current border-t-transparent rounded-full\" />\n </Show>\n <Show when={props.action.icon && !(isExecuting() && isExecutable())}>\n <span class=\"text-current\">{props.action.icon}</span>\n </Show>\n {props.action.label}\n </button>\n )\n}\n\n/**\n * Action group component for rendering multiple actions with consistent layout\n *\n * @example\n * ```tsx\n * const actionGroup: UIComponent = {\n * id: 'form-actions',\n * type: 'action-group',\n * position: { colStart: 1, colSpan: 12 },\n * params: {\n * layout: 'end',\n * gap: 'md',\n * actions: [\n * { label: 'Cancel', variant: 'outline', action: 'link', url: '/back' },\n * { label: 'Save', variant: 'primary', action: 'tool-call', toolName: 'save' },\n * ],\n * },\n * }\n * <ActionGroupRenderer component={actionGroup} />\n * ```\n */\nexport const ActionGroupRenderer: Component<ActionGroupRendererProps> = (props) => {\n const strings = useMCPUIStrings()\n const params = () => props.params || (props.component?.params as ActionGroupParams) || { actions: [] }\n\n const layoutClass = () => {\n switch (params()?.layout) {\n case 'vertical':\n return 'flex flex-col'\n case 'space-between':\n return 'flex justify-between'\n case 'end':\n return 'flex justify-end'\n case 'center':\n return 'flex justify-center'\n default: // horizontal\n return 'flex'\n }\n }\n\n const gapClass = () => {\n switch (params()?.gap) {\n case 'none':\n return 'gap-0'\n case 'sm':\n return 'gap-1'\n case 'lg':\n return 'gap-4'\n default: // md\n return 'gap-2'\n }\n }\n\n return (\n <div\n class={`${layoutClass()} ${gapClass()} ${params()?.fullWidth ? 'w-full' : ''}`}\n role=\"group\"\n aria-label={params()?.label || strings.actionGroupLabel}\n >\n <For each={params()?.actions || []}>\n {(action, index) => <ActionButton action={action} index={index()} />}\n </For>\n </div>\n )\n}\n"],"names":["ActionButton","props","execute","executeAction","isExecuting","useAction","isExecutable","action","handleClick","e","disabled","toolName","preventDefault","params","url","window","open","isDisabled","variantClass","variant","sizeClass","size","type","_el$","_$getNextElement","_tmpl$2","_el$3","firstChild","_el$4","_co$","_$getNextMarker","nextSibling","_el$5","_el$6","_co$2","_$insert","_$createComponent","Show","when","icon","children","_el$2","_tmpl$","label","_$effect","_p$","_v$","safeUrl","_v$2","_$setAttribute","t","_$className","undefined","_el$7","_tmpl$4","_el$0","_el$1","_co$3","_el$10","_el$11","_co$4","_el$12","_el$13","_co$5","$$click","_$memo","_tmpl$3","_el$9","_v$3","_v$4","_$setProperty","_$runHydrationEvents","ActionGroupRenderer","strings","useMCPUIStrings","component","actions","layoutClass","layout","gapClass","gap","_el$14","_tmpl$5","For","each","index","_v$5","fullWidth","_v$6","actionGroupLabel","_$delegateEvents"],"mappings":"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"}
@@ -31,17 +31,17 @@ const ActionButton = (props) => {
31
31
  const variantClass = () => {
32
32
  switch (props.action.variant) {
33
33
  case "primary":
34
- return "bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500";
34
+ return "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))] focus:ring-[color:var(--mcp-ui-focus,var(--color-blue-500))]";
35
35
  case "secondary":
36
- return "bg-gray-200 text-gray-800 hover:bg-gray-300 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600 focus:ring-gray-500";
36
+ return "bg-[color:var(--mcp-ui-surface-muted,var(--color-gray-200,#e5e7eb))] text-[color:var(--mcp-ui-fg,var(--color-gray-800,#1f2937))] hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-300,#d1d5db))] 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))] focus:ring-[color:var(--mcp-ui-focus,var(--color-gray-500,#6b7280))]";
37
37
  case "outline":
38
- return "border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 focus:ring-gray-500";
38
+ return "border border-[color:var(--mcp-ui-border,var(--color-gray-300,#d1d5db))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-600,#4b5563))] text-[color:var(--mcp-ui-fg,var(--color-gray-700,#374151))] dark:text-[color:var(--mcp-ui-fg,var(--color-gray-300,#d1d5db))] 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))] focus:ring-[color:var(--mcp-ui-focus,var(--color-gray-500,#6b7280))]";
39
39
  case "ghost":
40
- return "text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 focus:ring-gray-500";
40
+ return "text-[color:var(--mcp-ui-fg,var(--color-gray-700,#374151))] dark:text-[color:var(--mcp-ui-fg,var(--color-gray-300,#d1d5db))] 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))] focus:ring-[color:var(--mcp-ui-focus,var(--color-gray-500,#6b7280))]";
41
41
  case "danger":
42
- return "bg-red-600 text-white hover:bg-red-700 focus:ring-red-500";
42
+ return "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))] focus:ring-[color:var(--mcp-ui-focus,var(--color-red-500))]";
43
43
  default:
44
- return "bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500";
44
+ return "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))] focus:ring-[color:var(--mcp-ui-focus,var(--color-blue-500))]";
45
45
  }
46
46
  };
47
47
  const sizeClass = () => {
@@ -1 +1 @@
1
- {"version":3,"file":"ActionGroupRenderer.js","sources":["../../src/components/ActionGroupRenderer.tsx"],"sourcesContent":["/**\n * ActionGroupRenderer - Group of actions with layout options\n * Sprint 3: UX Improvements\n */\n\nimport { Component, For, Show } from 'solid-js'\nimport type { UIComponent, ActionGroupParams, ActionComponentParams } from '../types'\nimport { useAction } from '../hooks/useAction'\nimport { safeUrl } from '../utils/safe-url'\nimport { useMCPUIStrings } from '../context/MCPUIStringsContext'\n\nexport interface ActionGroupRendererProps {\n /**\n * UIComponent with action-group params (for declarative use)\n */\n component?: UIComponent\n\n /**\n * Direct action group params (alternative to component)\n */\n params?: ActionGroupParams\n}\n\n/**\n * Render a single action button with variants and click handling\n */\nconst ActionButton: Component<{\n action: ActionComponentParams\n index: number\n}> = (props) => {\n const { execute, executeAction, isExecuting } = useAction()\n\n // tool-call and submit both go through the host executor — they show a\n // loading state and gate disabled while running. link does neither.\n const isExecutable = () =>\n props.action.action === 'tool-call' || props.action.action === 'submit'\n\n const handleClick = async (e: MouseEvent) => {\n if (props.action.disabled) return\n\n if (props.action.action === 'tool-call' && props.action.toolName) {\n e.preventDefault()\n await execute(props.action.toolName, props.action.params || {})\n } else if (props.action.action === 'submit') {\n // submit is NOT a tool call — route it through the executor with the\n // `action: 'submit'` kind preserved so the host can POST to\n // params.submit_url etc. Works without a surrounding <form>.\n e.preventDefault()\n await executeAction({\n action: 'submit',\n toolName: props.action.toolName || 'submit',\n params: props.action.params || {},\n })\n } else if (props.action.action === 'link' && props.action.url) {\n window.open(props.action.url, '_blank', 'noopener,noreferrer')\n }\n }\n\n const isDisabled = () =>\n props.action.disabled || (isExecutable() && isExecuting())\n\n const variantClass = () => {\n switch (props.action.variant) {\n case 'primary':\n return 'bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500'\n case 'secondary':\n return 'bg-gray-200 text-gray-800 hover:bg-gray-300 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600 focus:ring-gray-500'\n case 'outline':\n return 'border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 focus:ring-gray-500'\n case 'ghost':\n return 'text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 focus:ring-gray-500'\n case 'danger':\n return 'bg-red-600 text-white hover:bg-red-700 focus:ring-red-500'\n default:\n return 'bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500'\n }\n }\n\n const sizeClass = () => {\n switch (props.action.size) {\n case 'sm':\n return 'px-2 py-1 text-xs'\n case 'lg':\n return 'px-6 py-3 text-base'\n default:\n return 'px-4 py-2 text-sm'\n }\n }\n\n // Render as link if it's a link action\n if (props.action.type === 'link' || (props.action.action === 'link' && props.action.url)) {\n return (\n <a\n href={safeUrl(props.action.url ?? '') ?? '#'}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class={`inline-flex items-center justify-center gap-2 rounded-md font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 ${variantClass()} ${sizeClass()} ${\n isDisabled() ? 'opacity-50 cursor-not-allowed pointer-events-none' : ''\n }`}\n >\n <Show when={props.action.icon}>\n <span class=\"text-current\">{props.action.icon}</span>\n </Show>\n {props.action.label}\n </a>\n )\n }\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={isDisabled()}\n class={`inline-flex items-center justify-center gap-2 rounded-md font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 ${variantClass()} ${sizeClass()} ${\n isDisabled() ? 'opacity-50 cursor-not-allowed' : ''\n }`}\n >\n <Show when={isExecuting() && isExecutable()}>\n <span class=\"animate-spin h-4 w-4 border-2 border-current border-t-transparent rounded-full\" />\n </Show>\n <Show when={props.action.icon && !(isExecuting() && isExecutable())}>\n <span class=\"text-current\">{props.action.icon}</span>\n </Show>\n {props.action.label}\n </button>\n )\n}\n\n/**\n * Action group component for rendering multiple actions with consistent layout\n *\n * @example\n * ```tsx\n * const actionGroup: UIComponent = {\n * id: 'form-actions',\n * type: 'action-group',\n * position: { colStart: 1, colSpan: 12 },\n * params: {\n * layout: 'end',\n * gap: 'md',\n * actions: [\n * { label: 'Cancel', variant: 'outline', action: 'link', url: '/back' },\n * { label: 'Save', variant: 'primary', action: 'tool-call', toolName: 'save' },\n * ],\n * },\n * }\n * <ActionGroupRenderer component={actionGroup} />\n * ```\n */\nexport const ActionGroupRenderer: Component<ActionGroupRendererProps> = (props) => {\n const strings = useMCPUIStrings()\n const params = () => props.params || (props.component?.params as ActionGroupParams) || { actions: [] }\n\n const layoutClass = () => {\n switch (params()?.layout) {\n case 'vertical':\n return 'flex flex-col'\n case 'space-between':\n return 'flex justify-between'\n case 'end':\n return 'flex justify-end'\n case 'center':\n return 'flex justify-center'\n default: // horizontal\n return 'flex'\n }\n }\n\n const gapClass = () => {\n switch (params()?.gap) {\n case 'none':\n return 'gap-0'\n case 'sm':\n return 'gap-1'\n case 'lg':\n return 'gap-4'\n default: // md\n return 'gap-2'\n }\n }\n\n return (\n <div\n class={`${layoutClass()} ${gapClass()} ${params()?.fullWidth ? 'w-full' : ''}`}\n role=\"group\"\n aria-label={params()?.label || strings.actionGroupLabel}\n >\n <For each={params()?.actions || []}>\n {(action, index) => <ActionButton action={action} index={index()} />}\n </For>\n </div>\n )\n}\n"],"names":["ActionButton","props","execute","executeAction","isExecuting","useAction","isExecutable","action","handleClick","e","disabled","toolName","preventDefault","params","url","window","open","isDisabled","variantClass","variant","sizeClass","size","type","_el$","_$getNextElement","_tmpl$2","_el$3","firstChild","_el$4","_co$","_$getNextMarker","nextSibling","_el$5","_el$6","_co$2","_$insert","_$createComponent","Show","when","icon","children","_el$2","_tmpl$","label","_$effect","_p$","_v$","safeUrl","_v$2","_$setAttribute","t","_$className","undefined","_el$7","_tmpl$4","_el$0","_el$1","_co$3","_el$10","_el$11","_co$4","_el$12","_el$13","_co$5","$$click","_$memo","_tmpl$3","_el$9","_v$3","_v$4","_$setProperty","_$runHydrationEvents","ActionGroupRenderer","strings","useMCPUIStrings","component","actions","layoutClass","layout","gapClass","gap","_el$14","_tmpl$5","For","each","index","_v$5","fullWidth","_v$6","actionGroupLabel","_$delegateEvents"],"mappings":"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"}
1
+ {"version":3,"file":"ActionGroupRenderer.js","sources":["../../src/components/ActionGroupRenderer.tsx"],"sourcesContent":["/**\n * ActionGroupRenderer - Group of actions with layout options\n * Sprint 3: UX Improvements\n */\n\nimport { Component, For, Show } from 'solid-js'\nimport type { UIComponent, ActionGroupParams, ActionComponentParams } from '../types'\nimport { useAction } from '../hooks/useAction'\nimport { safeUrl } from '../utils/safe-url'\nimport { useMCPUIStrings } from '../context/MCPUIStringsContext'\n\nexport interface ActionGroupRendererProps {\n /**\n * UIComponent with action-group params (for declarative use)\n */\n component?: UIComponent\n\n /**\n * Direct action group params (alternative to component)\n */\n params?: ActionGroupParams\n}\n\n/**\n * Render a single action button with variants and click handling\n */\nconst ActionButton: Component<{\n action: ActionComponentParams\n index: number\n}> = (props) => {\n const { execute, executeAction, isExecuting } = useAction()\n\n // tool-call and submit both go through the host executor — they show a\n // loading state and gate disabled while running. link does neither.\n const isExecutable = () =>\n props.action.action === 'tool-call' || props.action.action === 'submit'\n\n const handleClick = async (e: MouseEvent) => {\n if (props.action.disabled) return\n\n if (props.action.action === 'tool-call' && props.action.toolName) {\n e.preventDefault()\n await execute(props.action.toolName, props.action.params || {})\n } else if (props.action.action === 'submit') {\n // submit is NOT a tool call — route it through the executor with the\n // `action: 'submit'` kind preserved so the host can POST to\n // params.submit_url etc. Works without a surrounding <form>.\n e.preventDefault()\n await executeAction({\n action: 'submit',\n toolName: props.action.toolName || 'submit',\n params: props.action.params || {},\n })\n } else if (props.action.action === 'link' && props.action.url) {\n window.open(props.action.url, '_blank', 'noopener,noreferrer')\n }\n }\n\n const isDisabled = () =>\n props.action.disabled || (isExecutable() && isExecuting())\n\n const variantClass = () => {\n switch (props.action.variant) {\n case 'primary':\n return '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))] focus:ring-[color:var(--mcp-ui-focus,var(--color-blue-500))]'\n case 'secondary':\n return 'bg-[color:var(--mcp-ui-surface-muted,var(--color-gray-200,#e5e7eb))] text-[color:var(--mcp-ui-fg,var(--color-gray-800,#1f2937))] hover:bg-[color:var(--mcp-ui-surface-hover,var(--color-gray-300,#d1d5db))] 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))] focus:ring-[color:var(--mcp-ui-focus,var(--color-gray-500,#6b7280))]'\n case 'outline':\n return 'border border-[color:var(--mcp-ui-border,var(--color-gray-300,#d1d5db))] dark:border-[color:var(--mcp-ui-border,var(--color-gray-600,#4b5563))] text-[color:var(--mcp-ui-fg,var(--color-gray-700,#374151))] dark:text-[color:var(--mcp-ui-fg,var(--color-gray-300,#d1d5db))] 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))] focus:ring-[color:var(--mcp-ui-focus,var(--color-gray-500,#6b7280))]'\n case 'ghost':\n return 'text-[color:var(--mcp-ui-fg,var(--color-gray-700,#374151))] dark:text-[color:var(--mcp-ui-fg,var(--color-gray-300,#d1d5db))] 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))] focus:ring-[color:var(--mcp-ui-focus,var(--color-gray-500,#6b7280))]'\n case 'danger':\n return '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))] focus:ring-[color:var(--mcp-ui-focus,var(--color-red-500))]'\n default:\n return '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))] focus:ring-[color:var(--mcp-ui-focus,var(--color-blue-500))]'\n }\n }\n\n const sizeClass = () => {\n switch (props.action.size) {\n case 'sm':\n return 'px-2 py-1 text-xs'\n case 'lg':\n return 'px-6 py-3 text-base'\n default:\n return 'px-4 py-2 text-sm'\n }\n }\n\n // Render as link if it's a link action\n if (props.action.type === 'link' || (props.action.action === 'link' && props.action.url)) {\n return (\n <a\n href={safeUrl(props.action.url ?? '') ?? '#'}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class={`inline-flex items-center justify-center gap-2 rounded-md font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 ${variantClass()} ${sizeClass()} ${\n isDisabled() ? 'opacity-50 cursor-not-allowed pointer-events-none' : ''\n }`}\n >\n <Show when={props.action.icon}>\n <span class=\"text-current\">{props.action.icon}</span>\n </Show>\n {props.action.label}\n </a>\n )\n }\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={isDisabled()}\n class={`inline-flex items-center justify-center gap-2 rounded-md font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 ${variantClass()} ${sizeClass()} ${\n isDisabled() ? 'opacity-50 cursor-not-allowed' : ''\n }`}\n >\n <Show when={isExecuting() && isExecutable()}>\n <span class=\"animate-spin h-4 w-4 border-2 border-current border-t-transparent rounded-full\" />\n </Show>\n <Show when={props.action.icon && !(isExecuting() && isExecutable())}>\n <span class=\"text-current\">{props.action.icon}</span>\n </Show>\n {props.action.label}\n </button>\n )\n}\n\n/**\n * Action group component for rendering multiple actions with consistent layout\n *\n * @example\n * ```tsx\n * const actionGroup: UIComponent = {\n * id: 'form-actions',\n * type: 'action-group',\n * position: { colStart: 1, colSpan: 12 },\n * params: {\n * layout: 'end',\n * gap: 'md',\n * actions: [\n * { label: 'Cancel', variant: 'outline', action: 'link', url: '/back' },\n * { label: 'Save', variant: 'primary', action: 'tool-call', toolName: 'save' },\n * ],\n * },\n * }\n * <ActionGroupRenderer component={actionGroup} />\n * ```\n */\nexport const ActionGroupRenderer: Component<ActionGroupRendererProps> = (props) => {\n const strings = useMCPUIStrings()\n const params = () => props.params || (props.component?.params as ActionGroupParams) || { actions: [] }\n\n const layoutClass = () => {\n switch (params()?.layout) {\n case 'vertical':\n return 'flex flex-col'\n case 'space-between':\n return 'flex justify-between'\n case 'end':\n return 'flex justify-end'\n case 'center':\n return 'flex justify-center'\n default: // horizontal\n return 'flex'\n }\n }\n\n const gapClass = () => {\n switch (params()?.gap) {\n case 'none':\n return 'gap-0'\n case 'sm':\n return 'gap-1'\n case 'lg':\n return 'gap-4'\n default: // md\n return 'gap-2'\n }\n }\n\n return (\n <div\n class={`${layoutClass()} ${gapClass()} ${params()?.fullWidth ? 'w-full' : ''}`}\n role=\"group\"\n aria-label={params()?.label || strings.actionGroupLabel}\n >\n <For each={params()?.actions || []}>\n {(action, index) => <ActionButton action={action} index={index()} />}\n </For>\n </div>\n )\n}\n"],"names":["ActionButton","props","execute","executeAction","isExecuting","useAction","isExecutable","action","handleClick","e","disabled","toolName","preventDefault","params","url","window","open","isDisabled","variantClass","variant","sizeClass","size","type","_el$","_$getNextElement","_tmpl$2","_el$3","firstChild","_el$4","_co$","_$getNextMarker","nextSibling","_el$5","_el$6","_co$2","_$insert","_$createComponent","Show","when","icon","children","_el$2","_tmpl$","label","_$effect","_p$","_v$","safeUrl","_v$2","_$setAttribute","t","_$className","undefined","_el$7","_tmpl$4","_el$0","_el$1","_co$3","_el$10","_el$11","_co$4","_el$12","_el$13","_co$5","$$click","_$memo","_tmpl$3","_el$9","_v$3","_v$4","_$setProperty","_$runHydrationEvents","ActionGroupRenderer","strings","useMCPUIStrings","component","actions","layoutClass","layout","gapClass","gap","_el$14","_tmpl$5","For","each","index","_v$5","fullWidth","_v$6","actionGroupLabel","_$delegateEvents"],"mappings":"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"}
@@ -3,7 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const web = require("solid-js/web");
4
4
  const solidJs = require("solid-js");
5
5
  const MCPUIStringsContext = require("../context/MCPUIStringsContext.cjs");
6
- var _tmpl$ = /* @__PURE__ */ web.template(`<strong class=mcp-autocomplete-highlight>`), _tmpl$2 = /* @__PURE__ */ web.template(`<span class=mcp-autocomplete-option-icon>`), _tmpl$3 = /* @__PURE__ */ web.template(`<span class=mcp-autocomplete-option-description>`), _tmpl$4 = /* @__PURE__ */ web.template(`<div class=mcp-autocomplete-option-content><!$><!/><div class=mcp-autocomplete-option-text><span class=mcp-autocomplete-option-label></span><!$><!/>`), _tmpl$5 = /* @__PURE__ */ web.template(`<div class=mcp-autocomplete-loading style="padding:12px 16px;color:#6b7280;font-size:0.875rem;display:flex;align-items:center;gap:8px"><span style="display:inline-block;width:14px;height:14px;border:2px solid #e5e7eb;border-top-color:#3b82f6;border-radius:50%;animation:mcp-spin 0.6s linear infinite"></span><!$><!/>`), _tmpl$6 = /* @__PURE__ */ web.template(`<div class=mcp-autocomplete-empty style="padding:12px 16px;color:#9ca3af;font-size:0.875rem;text-align:center">`), _tmpl$7 = /* @__PURE__ */ web.template(`<ul class=mcp-autocomplete-options style="margin:0;padding:4px 0;list-style:none">`), _tmpl$8 = /* @__PURE__ */ web.template(`<div class=mcp-autocomplete-footer style="padding:6px 12px;border-top:1px solid #e5e7eb;background-color:#f9fafb;font-size:0.75rem;color:#6b7280"><kbd style="background-color:#e5e7eb;padding:1px 4px;border-radius:2px;font-family:inherit;font-size:0.7rem">↑</kbd> <kbd style="background-color:#e5e7eb;padding:1px 4px;border-radius:2px;font-family:inherit;font-size:0.7rem">↓</kbd><!$><!/><kbd style="background-color:#e5e7eb;padding:1px 4px;border-radius:2px;font-family:inherit;font-size:0.7rem">Enter</kbd><!$><!/><kbd style="background-color:#e5e7eb;padding:1px 4px;border-radius:2px;font-family:inherit;font-size:0.7rem">Esc</kbd><!$><!/>`), _tmpl$9 = /* @__PURE__ */ web.template(`<div role=listbox><!$><!/><!$><!/><!$><!/><!$><!/>`), _tmpl$0 = /* @__PURE__ */ web.template(`<li role=option style="padding:8px 16px;font-size:0.875rem;transition:background-color 150ms ease">`);
6
+ var _tmpl$ = /* @__PURE__ */ web.template(`<strong class=mcp-autocomplete-highlight>`), _tmpl$2 = /* @__PURE__ */ web.template(`<span class=mcp-autocomplete-option-icon>`), _tmpl$3 = /* @__PURE__ */ web.template(`<span class=mcp-autocomplete-option-description>`), _tmpl$4 = /* @__PURE__ */ web.template(`<div class=mcp-autocomplete-option-content><!$><!/><div class=mcp-autocomplete-option-text><span class=mcp-autocomplete-option-label></span><!$><!/>`), _tmpl$5 = /* @__PURE__ */ web.template(`<div class=mcp-autocomplete-loading style="padding:12px 16px;color:var(--mcp-ui-fg-muted, #6b7280);font-size:0.875rem;display:flex;align-items:center;gap:8px"><span style="display:inline-block;width:14px;height:14px;border:2px solid var(--mcp-ui-border, #e5e7eb);border-top-color:var(--mcp-ui-accent, #3b82f6);border-radius:50%;animation:mcp-spin 0.6s linear infinite"></span><!$><!/>`), _tmpl$6 = /* @__PURE__ */ web.template(`<div class=mcp-autocomplete-empty style="padding:12px 16px;color:var(--mcp-ui-fg-subtle, #9ca3af);font-size:0.875rem;text-align:center">`), _tmpl$7 = /* @__PURE__ */ web.template(`<ul class=mcp-autocomplete-options style="margin:0;padding:4px 0;list-style:none">`), _tmpl$8 = /* @__PURE__ */ web.template(`<div class=mcp-autocomplete-footer style="padding:6px 12px;border-top:1px solid var(--mcp-ui-border, #e5e7eb);background-color:var(--mcp-ui-surface-muted, #f9fafb);font-size:0.75rem;color:var(--mcp-ui-fg-muted, #6b7280)"><kbd style="background-color:var(--mcp-ui-surface-hover, #e5e7eb);padding:1px 4px;border-radius:2px;font-family:inherit;font-size:0.7rem">↑</kbd> <kbd style="background-color:var(--mcp-ui-surface-hover, #e5e7eb);padding:1px 4px;border-radius:2px;font-family:inherit;font-size:0.7rem">↓</kbd><!$><!/><kbd style="background-color:var(--mcp-ui-surface-hover, #e5e7eb);padding:1px 4px;border-radius:2px;font-family:inherit;font-size:0.7rem">Enter</kbd><!$><!/><kbd style="background-color:var(--mcp-ui-surface-hover, #e5e7eb);padding:1px 4px;border-radius:2px;font-family:inherit;font-size:0.7rem">Esc</kbd><!$><!/>`), _tmpl$9 = /* @__PURE__ */ web.template(`<div role=listbox><!$><!/><!$><!/><!$><!/><!$><!/>`), _tmpl$0 = /* @__PURE__ */ web.template(`<li role=option style="padding:8px 16px;font-size:0.875rem;transition:background-color 150ms ease">`);
7
7
  function highlightText(text, match) {
8
8
  if (!match || !text) {
9
9
  return text;
@@ -70,10 +70,10 @@ const AutocompleteDropdown = (props) => {
70
70
  left: "0",
71
71
  right: "0",
72
72
  "z-index": "50",
73
- "background-color": "#ffffff",
74
- border: "1px solid #e5e7eb",
73
+ "background-color": "var(--mcp-ui-surface, #ffffff)",
74
+ border: "1px solid var(--mcp-ui-border, #e5e7eb)",
75
75
  "border-radius": "6px",
76
- "box-shadow": "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)",
76
+ "box-shadow": "var(--mcp-ui-shadow, 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06))",
77
77
  "max-height": props.maxHeight || "240px",
78
78
  overflow: "auto",
79
79
  ...positionStyles()
@@ -150,7 +150,7 @@ const AutocompleteDropdown = (props) => {
150
150
  }
151
151
  }));
152
152
  web.effect((_p$) => {
153
- var _v$4 = isSelected(), _v$5 = isDisabled(), _v$6 = `mcp-autocomplete-option ${isSelected() ? "mcp-autocomplete-option-selected" : ""} ${isDisabled() ? "mcp-autocomplete-option-disabled" : ""}`, _v$7 = isDisabled() ? "not-allowed" : "pointer", _v$8 = isSelected() ? "#eff6ff" : "transparent", _v$9 = isDisabled() ? "#9ca3af" : "#374151";
153
+ var _v$4 = isSelected(), _v$5 = isDisabled(), _v$6 = `mcp-autocomplete-option ${isSelected() ? "mcp-autocomplete-option-selected" : ""} ${isDisabled() ? "mcp-autocomplete-option-disabled" : ""}`, _v$7 = isDisabled() ? "not-allowed" : "pointer", _v$8 = isSelected() ? "var(--mcp-ui-accent-soft, #eff6ff)" : "transparent", _v$9 = isDisabled() ? "var(--mcp-ui-fg-subtle, #9ca3af)" : "var(--mcp-ui-fg, #374151)";
154
154
  _v$4 !== _p$.e && web.setAttribute(_el$36, "aria-selected", _p$.e = _v$4);
155
155
  _v$5 !== _p$.t && web.setAttribute(_el$36, "aria-disabled", _p$.t = _v$5);
156
156
  _v$6 !== _p$.a && web.className(_el$36, _p$.a = _v$6);
@@ -187,7 +187,7 @@ const AutocompleteDropdown = (props) => {
187
187
  }
188
188
  }), _el$35, _co$0);
189
189
  web.effect((_p$) => {
190
- var _v$ = `mcp-autocomplete-dropdown ${props.class || ""}`, _v$2 = containerStyles(), _v$3 = strings.autocompleteSuggestions;
190
+ var _v$ = `mcp-ui-root mcp-autocomplete-dropdown ${props.class || ""}`, _v$2 = containerStyles(), _v$3 = strings.autocompleteSuggestions;
191
191
  _v$ !== _p$.e && web.className(_el$1, _p$.e = _v$);
192
192
  _p$.t = web.style(_el$1, _v$2, _p$.t);
193
193
  _v$3 !== _p$.a && web.setAttribute(_el$1, "aria-label", _p$.a = _v$3);
@@ -1 +1 @@
1
- {"version":3,"file":"AutocompleteDropdown.cjs","sources":["../../src/components/AutocompleteDropdown.tsx"],"sourcesContent":["/**\n * AutocompleteDropdown Component\n * Displays data-driven dropdown suggestions\n *\n * Sprint Autocomplete Feature\n */\n\nimport { Component, For, Show, createMemo, JSX } from 'solid-js'\nimport type { AutocompleteOption } from '../types'\nimport { useMCPUIStrings } from '../context/MCPUIStringsContext'\n\n/**\n * Props for AutocompleteDropdown\n */\nexport interface AutocompleteDropdownProps {\n /**\n * Options to display\n */\n options: AutocompleteOption[]\n\n /**\n * Currently selected index\n */\n selectedIndex: number\n\n /**\n * Whether dropdown is visible\n */\n isOpen: boolean\n\n /**\n * Callback when option is selected\n */\n onSelect: (option: AutocompleteOption) => void\n\n /**\n * Callback when option is hovered\n */\n onHover?: (index: number) => void\n\n /**\n * Whether loading\n */\n isLoading?: boolean\n\n /**\n * Custom class\n */\n class?: string\n\n /**\n * Max height\n */\n maxHeight?: string\n\n /**\n * Empty state message\n */\n emptyMessage?: string\n\n /**\n * Loading message\n */\n loadingMessage?: string\n\n /**\n * Highlight matching text in options\n */\n highlightMatch?: string\n\n /**\n * Position (default: 'bottom')\n */\n position?: 'top' | 'bottom'\n\n /**\n * Custom option renderer\n */\n renderOption?: (option: AutocompleteOption, isSelected: boolean) => JSX.Element\n}\n\n/**\n * Highlight matching text\n */\nfunction highlightText(text: string, match?: string): JSX.Element {\n if (!match || !text) {\n return <>{text}</>\n }\n\n const lowerText = text.toLowerCase()\n const lowerMatch = match.toLowerCase()\n const startIndex = lowerText.indexOf(lowerMatch)\n\n if (startIndex === -1) {\n return <>{text}</>\n }\n\n const before = text.slice(0, startIndex)\n const matched = text.slice(startIndex, startIndex + match.length)\n const after = text.slice(startIndex + match.length)\n\n return (\n <>\n {before}\n <strong class=\"mcp-autocomplete-highlight\">{matched}</strong>\n {after}\n </>\n )\n}\n\n/**\n * Default option renderer\n */\nconst DefaultOptionRenderer: Component<{\n option: AutocompleteOption\n isSelected: boolean\n highlightMatch?: string\n}> = (props) => {\n const displayLabel = createMemo(() =>\n props.option.label || props.option.value\n )\n\n return (\n <div class=\"mcp-autocomplete-option-content\">\n <Show when={props.option.icon}>\n <span class=\"mcp-autocomplete-option-icon\">{props.option.icon}</span>\n </Show>\n <div class=\"mcp-autocomplete-option-text\">\n <span class=\"mcp-autocomplete-option-label\">\n {highlightText(displayLabel(), props.highlightMatch)}\n </span>\n <Show when={props.option.description}>\n <span class=\"mcp-autocomplete-option-description\">\n {props.option.description}\n </span>\n </Show>\n </div>\n </div>\n )\n}\n\n/**\n * AutocompleteDropdown Component\n */\nexport const AutocompleteDropdown: Component<AutocompleteDropdownProps> = (props) => {\n const strings = useMCPUIStrings()\n const positionStyles = createMemo((): JSX.CSSProperties => {\n if (props.position === 'top') {\n return {\n bottom: '100%',\n 'margin-bottom': '4px'\n }\n }\n return {\n top: '100%',\n 'margin-top': '4px'\n }\n })\n\n const containerStyles = createMemo((): JSX.CSSProperties => ({\n position: 'absolute',\n left: '0',\n right: '0',\n 'z-index': '50',\n 'background-color': '#ffffff',\n border: '1px solid #e5e7eb',\n 'border-radius': '6px',\n 'box-shadow': '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',\n 'max-height': props.maxHeight || '240px',\n overflow: 'auto',\n ...positionStyles()\n }))\n\n return (\n <Show when={props.isOpen}>\n <div\n class={`mcp-autocomplete-dropdown ${props.class || ''}`}\n style={containerStyles()}\n role=\"listbox\"\n aria-label={strings.autocompleteSuggestions}\n >\n {/* Loading state */}\n <Show when={props.isLoading}>\n <div\n class=\"mcp-autocomplete-loading\"\n style={{\n padding: '12px 16px',\n color: '#6b7280',\n 'font-size': '0.875rem',\n display: 'flex',\n 'align-items': 'center',\n gap: '8px'\n }}\n >\n <span\n style={{\n display: 'inline-block',\n width: '14px',\n height: '14px',\n border: '2px solid #e5e7eb',\n 'border-top-color': '#3b82f6',\n 'border-radius': '50%',\n animation: 'mcp-spin 0.6s linear infinite'\n }}\n />\n {props.loadingMessage || strings.autocompleteLoading}\n </div>\n </Show>\n\n {/* Empty state */}\n <Show when={!props.isLoading && props.options.length === 0}>\n <div\n class=\"mcp-autocomplete-empty\"\n style={{\n padding: '12px 16px',\n color: '#9ca3af',\n 'font-size': '0.875rem',\n 'text-align': 'center'\n }}\n >\n {props.emptyMessage || strings.autocompleteEmpty}\n </div>\n </Show>\n\n {/* Options list */}\n <Show when={!props.isLoading && props.options.length > 0}>\n <ul\n class=\"mcp-autocomplete-options\"\n style={{ margin: '0', padding: '4px 0', 'list-style': 'none' }}\n >\n <For each={props.options}>\n {(option, index) => {\n const isSelected = () => index() === props.selectedIndex\n const isDisabled = () => option.disabled\n\n return (\n <li\n role=\"option\"\n aria-selected={isSelected()}\n aria-disabled={isDisabled()}\n class={`mcp-autocomplete-option ${isSelected() ? 'mcp-autocomplete-option-selected' : ''} ${isDisabled() ? 'mcp-autocomplete-option-disabled' : ''}`}\n style={{\n padding: '8px 16px',\n cursor: isDisabled() ? 'not-allowed' : 'pointer',\n 'background-color': isSelected() ? '#eff6ff' : 'transparent',\n color: isDisabled() ? '#9ca3af' : '#374151',\n 'font-size': '0.875rem',\n transition: 'background-color 150ms ease'\n }}\n onClick={() => {\n if (!isDisabled()) {\n props.onSelect(option)\n }\n }}\n onMouseEnter={() => {\n if (!isDisabled()) {\n props.onHover?.(index())\n }\n }}\n >\n <Show\n when={props.renderOption}\n fallback={\n <DefaultOptionRenderer\n option={option}\n isSelected={isSelected()}\n highlightMatch={props.highlightMatch}\n />\n }\n >\n {props.renderOption!(option, isSelected())}\n </Show>\n </li>\n )\n }}\n </For>\n </ul>\n </Show>\n\n {/* Footer hint */}\n <Show when={!props.isLoading && props.options.length > 0}>\n <div\n class=\"mcp-autocomplete-footer\"\n style={{\n padding: '6px 12px',\n 'border-top': '1px solid #e5e7eb',\n 'background-color': '#f9fafb',\n 'font-size': '0.75rem',\n color: '#6b7280'\n }}\n >\n <kbd style={{\n 'background-color': '#e5e7eb',\n padding: '1px 4px',\n 'border-radius': '2px',\n 'font-family': 'inherit',\n 'font-size': '0.7rem'\n }}>↑</kbd>\n {' '}\n <kbd style={{\n 'background-color': '#e5e7eb',\n padding: '1px 4px',\n 'border-radius': '2px',\n 'font-family': 'inherit',\n 'font-size': '0.7rem'\n }}>↓</kbd>\n {strings.autocompleteHintNavigate}\n <kbd style={{\n 'background-color': '#e5e7eb',\n padding: '1px 4px',\n 'border-radius': '2px',\n 'font-family': 'inherit',\n 'font-size': '0.7rem'\n }}>Enter</kbd>\n {strings.autocompleteHintSelect}\n <kbd style={{\n 'background-color': '#e5e7eb',\n padding: '1px 4px',\n 'border-radius': '2px',\n 'font-family': 'inherit',\n 'font-size': '0.7rem'\n }}>Esc</kbd>\n {strings.autocompleteHintDismiss}\n </div>\n </Show>\n </div>\n </Show>\n )\n}\n\nexport default AutocompleteDropdown\n"],"names":["highlightText","text","match","lowerText","toLowerCase","lowerMatch","startIndex","indexOf","before","slice","matched","length","after","_el$","_$getNextElement","_tmpl$","_$insert","DefaultOptionRenderer","props","displayLabel","createMemo","option","label","value","_el$2","_tmpl$4","_el$9","firstChild","_el$0","_co$2","_$getNextMarker","nextSibling","_el$4","_el$5","_el$7","_el$8","_co$","_$createComponent","Show","when","icon","children","_el$3","_tmpl$2","highlightMatch","description","_el$6","_tmpl$3","AutocompleteDropdown","strings","useMCPUIStrings","positionStyles","position","bottom","top","containerStyles","left","right","border","maxHeight","overflow","isOpen","_el$1","_tmpl$9","_el$28","_el$29","_co$7","_el$30","_el$31","_co$8","_el$32","_el$33","_co$9","_el$34","_el$35","_co$0","isLoading","_el$10","_tmpl$5","_el$11","_el$12","_el$13","_co$3","loadingMessage","autocompleteLoading","_$memo","options","_el$14","_tmpl$6","emptyMessage","autocompleteEmpty","_el$15","_tmpl$7","For","each","index","isSelected","selectedIndex","isDisabled","disabled","_el$36","_tmpl$0","addEventListener","onHover","$$click","onSelect","renderOption","fallback","_$effect","_p$","_v$4","_v$5","_v$6","_v$7","_v$8","_v$9","e","_$setAttribute","t","a","_$className","o","_$setStyleProperty","i","n","undefined","_$runHydrationEvents","_el$16","_tmpl$8","_el$17","_el$18","_el$19","_el$22","_el$23","_co$4","_el$20","_el$24","_el$25","_co$5","_el$21","_el$26","_el$27","_co$6","autocompleteHintNavigate","autocompleteHintSelect","autocompleteHintDismiss","_v$","class","_v$2","_v$3","autocompleteSuggestions","_$style","_$delegateEvents"],"mappings":"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"}
1
+ {"version":3,"file":"AutocompleteDropdown.cjs","sources":["../../src/components/AutocompleteDropdown.tsx"],"sourcesContent":["/**\n * AutocompleteDropdown Component\n * Displays data-driven dropdown suggestions\n *\n * Sprint Autocomplete Feature\n */\n\nimport { Component, For, Show, createMemo, JSX } from 'solid-js'\nimport type { AutocompleteOption } from '../types'\nimport { useMCPUIStrings } from '../context/MCPUIStringsContext'\n\n/**\n * Props for AutocompleteDropdown\n */\nexport interface AutocompleteDropdownProps {\n /**\n * Options to display\n */\n options: AutocompleteOption[]\n\n /**\n * Currently selected index\n */\n selectedIndex: number\n\n /**\n * Whether dropdown is visible\n */\n isOpen: boolean\n\n /**\n * Callback when option is selected\n */\n onSelect: (option: AutocompleteOption) => void\n\n /**\n * Callback when option is hovered\n */\n onHover?: (index: number) => void\n\n /**\n * Whether loading\n */\n isLoading?: boolean\n\n /**\n * Custom class\n */\n class?: string\n\n /**\n * Max height\n */\n maxHeight?: string\n\n /**\n * Empty state message\n */\n emptyMessage?: string\n\n /**\n * Loading message\n */\n loadingMessage?: string\n\n /**\n * Highlight matching text in options\n */\n highlightMatch?: string\n\n /**\n * Position (default: 'bottom')\n */\n position?: 'top' | 'bottom'\n\n /**\n * Custom option renderer\n */\n renderOption?: (option: AutocompleteOption, isSelected: boolean) => JSX.Element\n}\n\n/**\n * Highlight matching text\n */\nfunction highlightText(text: string, match?: string): JSX.Element {\n if (!match || !text) {\n return <>{text}</>\n }\n\n const lowerText = text.toLowerCase()\n const lowerMatch = match.toLowerCase()\n const startIndex = lowerText.indexOf(lowerMatch)\n\n if (startIndex === -1) {\n return <>{text}</>\n }\n\n const before = text.slice(0, startIndex)\n const matched = text.slice(startIndex, startIndex + match.length)\n const after = text.slice(startIndex + match.length)\n\n return (\n <>\n {before}\n <strong class=\"mcp-autocomplete-highlight\">{matched}</strong>\n {after}\n </>\n )\n}\n\n/**\n * Default option renderer\n */\nconst DefaultOptionRenderer: Component<{\n option: AutocompleteOption\n isSelected: boolean\n highlightMatch?: string\n}> = (props) => {\n const displayLabel = createMemo(() =>\n props.option.label || props.option.value\n )\n\n return (\n <div class=\"mcp-autocomplete-option-content\">\n <Show when={props.option.icon}>\n <span class=\"mcp-autocomplete-option-icon\">{props.option.icon}</span>\n </Show>\n <div class=\"mcp-autocomplete-option-text\">\n <span class=\"mcp-autocomplete-option-label\">\n {highlightText(displayLabel(), props.highlightMatch)}\n </span>\n <Show when={props.option.description}>\n <span class=\"mcp-autocomplete-option-description\">\n {props.option.description}\n </span>\n </Show>\n </div>\n </div>\n )\n}\n\n/**\n * AutocompleteDropdown Component\n */\nexport const AutocompleteDropdown: Component<AutocompleteDropdownProps> = (props) => {\n const strings = useMCPUIStrings()\n const positionStyles = createMemo((): JSX.CSSProperties => {\n if (props.position === 'top') {\n return {\n bottom: '100%',\n 'margin-bottom': '4px'\n }\n }\n return {\n top: '100%',\n 'margin-top': '4px'\n }\n })\n\n const containerStyles = createMemo((): JSX.CSSProperties => ({\n position: 'absolute',\n left: '0',\n right: '0',\n 'z-index': '50',\n 'background-color': 'var(--mcp-ui-surface, #ffffff)',\n border: '1px solid var(--mcp-ui-border, #e5e7eb)',\n 'border-radius': '6px',\n 'box-shadow': 'var(--mcp-ui-shadow, 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06))',\n 'max-height': props.maxHeight || '240px',\n overflow: 'auto',\n ...positionStyles()\n }))\n\n return (\n <Show when={props.isOpen}>\n <div\n class={`mcp-ui-root mcp-autocomplete-dropdown ${props.class || ''}`}\n style={containerStyles()}\n role=\"listbox\"\n aria-label={strings.autocompleteSuggestions}\n >\n {/* Loading state */}\n <Show when={props.isLoading}>\n <div\n class=\"mcp-autocomplete-loading\"\n style={{\n padding: '12px 16px',\n color: 'var(--mcp-ui-fg-muted, #6b7280)',\n 'font-size': '0.875rem',\n display: 'flex',\n 'align-items': 'center',\n gap: '8px'\n }}\n >\n <span\n style={{\n display: 'inline-block',\n width: '14px',\n height: '14px',\n border: '2px solid var(--mcp-ui-border, #e5e7eb)',\n 'border-top-color': 'var(--mcp-ui-accent, #3b82f6)',\n 'border-radius': '50%',\n animation: 'mcp-spin 0.6s linear infinite'\n }}\n />\n {props.loadingMessage || strings.autocompleteLoading}\n </div>\n </Show>\n\n {/* Empty state */}\n <Show when={!props.isLoading && props.options.length === 0}>\n <div\n class=\"mcp-autocomplete-empty\"\n style={{\n padding: '12px 16px',\n color: 'var(--mcp-ui-fg-subtle, #9ca3af)',\n 'font-size': '0.875rem',\n 'text-align': 'center'\n }}\n >\n {props.emptyMessage || strings.autocompleteEmpty}\n </div>\n </Show>\n\n {/* Options list */}\n <Show when={!props.isLoading && props.options.length > 0}>\n <ul\n class=\"mcp-autocomplete-options\"\n style={{ margin: '0', padding: '4px 0', 'list-style': 'none' }}\n >\n <For each={props.options}>\n {(option, index) => {\n const isSelected = () => index() === props.selectedIndex\n const isDisabled = () => option.disabled\n\n return (\n <li\n role=\"option\"\n aria-selected={isSelected()}\n aria-disabled={isDisabled()}\n class={`mcp-autocomplete-option ${isSelected() ? 'mcp-autocomplete-option-selected' : ''} ${isDisabled() ? 'mcp-autocomplete-option-disabled' : ''}`}\n style={{\n padding: '8px 16px',\n cursor: isDisabled() ? 'not-allowed' : 'pointer',\n 'background-color': isSelected() ? 'var(--mcp-ui-accent-soft, #eff6ff)' : 'transparent',\n color: isDisabled() ? 'var(--mcp-ui-fg-subtle, #9ca3af)' : 'var(--mcp-ui-fg, #374151)',\n 'font-size': '0.875rem',\n transition: 'background-color 150ms ease'\n }}\n onClick={() => {\n if (!isDisabled()) {\n props.onSelect(option)\n }\n }}\n onMouseEnter={() => {\n if (!isDisabled()) {\n props.onHover?.(index())\n }\n }}\n >\n <Show\n when={props.renderOption}\n fallback={\n <DefaultOptionRenderer\n option={option}\n isSelected={isSelected()}\n highlightMatch={props.highlightMatch}\n />\n }\n >\n {props.renderOption!(option, isSelected())}\n </Show>\n </li>\n )\n }}\n </For>\n </ul>\n </Show>\n\n {/* Footer hint */}\n <Show when={!props.isLoading && props.options.length > 0}>\n <div\n class=\"mcp-autocomplete-footer\"\n style={{\n padding: '6px 12px',\n 'border-top': '1px solid var(--mcp-ui-border, #e5e7eb)',\n 'background-color': 'var(--mcp-ui-surface-muted, #f9fafb)',\n 'font-size': '0.75rem',\n color: 'var(--mcp-ui-fg-muted, #6b7280)'\n }}\n >\n <kbd style={{\n 'background-color': 'var(--mcp-ui-surface-hover, #e5e7eb)',\n padding: '1px 4px',\n 'border-radius': '2px',\n 'font-family': 'inherit',\n 'font-size': '0.7rem'\n }}>↑</kbd>\n {' '}\n <kbd style={{\n 'background-color': 'var(--mcp-ui-surface-hover, #e5e7eb)',\n padding: '1px 4px',\n 'border-radius': '2px',\n 'font-family': 'inherit',\n 'font-size': '0.7rem'\n }}>↓</kbd>\n {strings.autocompleteHintNavigate}\n <kbd style={{\n 'background-color': 'var(--mcp-ui-surface-hover, #e5e7eb)',\n padding: '1px 4px',\n 'border-radius': '2px',\n 'font-family': 'inherit',\n 'font-size': '0.7rem'\n }}>Enter</kbd>\n {strings.autocompleteHintSelect}\n <kbd style={{\n 'background-color': 'var(--mcp-ui-surface-hover, #e5e7eb)',\n padding: '1px 4px',\n 'border-radius': '2px',\n 'font-family': 'inherit',\n 'font-size': '0.7rem'\n }}>Esc</kbd>\n {strings.autocompleteHintDismiss}\n </div>\n </Show>\n </div>\n </Show>\n )\n}\n\nexport default AutocompleteDropdown\n"],"names":["highlightText","text","match","lowerText","toLowerCase","lowerMatch","startIndex","indexOf","before","slice","matched","length","after","_el$","_$getNextElement","_tmpl$","_$insert","DefaultOptionRenderer","props","displayLabel","createMemo","option","label","value","_el$2","_tmpl$4","_el$9","firstChild","_el$0","_co$2","_$getNextMarker","nextSibling","_el$4","_el$5","_el$7","_el$8","_co$","_$createComponent","Show","when","icon","children","_el$3","_tmpl$2","highlightMatch","description","_el$6","_tmpl$3","AutocompleteDropdown","strings","useMCPUIStrings","positionStyles","position","bottom","top","containerStyles","left","right","border","maxHeight","overflow","isOpen","_el$1","_tmpl$9","_el$28","_el$29","_co$7","_el$30","_el$31","_co$8","_el$32","_el$33","_co$9","_el$34","_el$35","_co$0","isLoading","_el$10","_tmpl$5","_el$11","_el$12","_el$13","_co$3","loadingMessage","autocompleteLoading","_$memo","options","_el$14","_tmpl$6","emptyMessage","autocompleteEmpty","_el$15","_tmpl$7","For","each","index","isSelected","selectedIndex","isDisabled","disabled","_el$36","_tmpl$0","addEventListener","onHover","$$click","onSelect","renderOption","fallback","_$effect","_p$","_v$4","_v$5","_v$6","_v$7","_v$8","_v$9","e","_$setAttribute","t","a","_$className","o","_$setStyleProperty","i","n","undefined","_$runHydrationEvents","_el$16","_tmpl$8","_el$17","_el$18","_el$19","_el$22","_el$23","_co$4","_el$20","_el$24","_el$25","_co$5","_el$21","_el$26","_el$27","_co$6","autocompleteHintNavigate","autocompleteHintSelect","autocompleteHintDismiss","_v$","class","_v$2","_v$3","autocompleteSuggestions","_$style","_$delegateEvents"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { createComponent, getNextElement, getNextMarker, insert, memo, effect, setAttribute, className, setStyleProperty, runHydrationEvents, style, template, delegateEvents } from "solid-js/web";
2
2
  import { createMemo, Show, For } from "solid-js";
3
3
  import { useMCPUIStrings } from "../context/MCPUIStringsContext.js";
4
- var _tmpl$ = /* @__PURE__ */ template(`<strong class=mcp-autocomplete-highlight>`), _tmpl$2 = /* @__PURE__ */ template(`<span class=mcp-autocomplete-option-icon>`), _tmpl$3 = /* @__PURE__ */ template(`<span class=mcp-autocomplete-option-description>`), _tmpl$4 = /* @__PURE__ */ template(`<div class=mcp-autocomplete-option-content><!$><!/><div class=mcp-autocomplete-option-text><span class=mcp-autocomplete-option-label></span><!$><!/>`), _tmpl$5 = /* @__PURE__ */ template(`<div class=mcp-autocomplete-loading style="padding:12px 16px;color:#6b7280;font-size:0.875rem;display:flex;align-items:center;gap:8px"><span style="display:inline-block;width:14px;height:14px;border:2px solid #e5e7eb;border-top-color:#3b82f6;border-radius:50%;animation:mcp-spin 0.6s linear infinite"></span><!$><!/>`), _tmpl$6 = /* @__PURE__ */ template(`<div class=mcp-autocomplete-empty style="padding:12px 16px;color:#9ca3af;font-size:0.875rem;text-align:center">`), _tmpl$7 = /* @__PURE__ */ template(`<ul class=mcp-autocomplete-options style="margin:0;padding:4px 0;list-style:none">`), _tmpl$8 = /* @__PURE__ */ template(`<div class=mcp-autocomplete-footer style="padding:6px 12px;border-top:1px solid #e5e7eb;background-color:#f9fafb;font-size:0.75rem;color:#6b7280"><kbd style="background-color:#e5e7eb;padding:1px 4px;border-radius:2px;font-family:inherit;font-size:0.7rem">↑</kbd> <kbd style="background-color:#e5e7eb;padding:1px 4px;border-radius:2px;font-family:inherit;font-size:0.7rem">↓</kbd><!$><!/><kbd style="background-color:#e5e7eb;padding:1px 4px;border-radius:2px;font-family:inherit;font-size:0.7rem">Enter</kbd><!$><!/><kbd style="background-color:#e5e7eb;padding:1px 4px;border-radius:2px;font-family:inherit;font-size:0.7rem">Esc</kbd><!$><!/>`), _tmpl$9 = /* @__PURE__ */ template(`<div role=listbox><!$><!/><!$><!/><!$><!/><!$><!/>`), _tmpl$0 = /* @__PURE__ */ template(`<li role=option style="padding:8px 16px;font-size:0.875rem;transition:background-color 150ms ease">`);
4
+ var _tmpl$ = /* @__PURE__ */ template(`<strong class=mcp-autocomplete-highlight>`), _tmpl$2 = /* @__PURE__ */ template(`<span class=mcp-autocomplete-option-icon>`), _tmpl$3 = /* @__PURE__ */ template(`<span class=mcp-autocomplete-option-description>`), _tmpl$4 = /* @__PURE__ */ template(`<div class=mcp-autocomplete-option-content><!$><!/><div class=mcp-autocomplete-option-text><span class=mcp-autocomplete-option-label></span><!$><!/>`), _tmpl$5 = /* @__PURE__ */ template(`<div class=mcp-autocomplete-loading style="padding:12px 16px;color:var(--mcp-ui-fg-muted, #6b7280);font-size:0.875rem;display:flex;align-items:center;gap:8px"><span style="display:inline-block;width:14px;height:14px;border:2px solid var(--mcp-ui-border, #e5e7eb);border-top-color:var(--mcp-ui-accent, #3b82f6);border-radius:50%;animation:mcp-spin 0.6s linear infinite"></span><!$><!/>`), _tmpl$6 = /* @__PURE__ */ template(`<div class=mcp-autocomplete-empty style="padding:12px 16px;color:var(--mcp-ui-fg-subtle, #9ca3af);font-size:0.875rem;text-align:center">`), _tmpl$7 = /* @__PURE__ */ template(`<ul class=mcp-autocomplete-options style="margin:0;padding:4px 0;list-style:none">`), _tmpl$8 = /* @__PURE__ */ template(`<div class=mcp-autocomplete-footer style="padding:6px 12px;border-top:1px solid var(--mcp-ui-border, #e5e7eb);background-color:var(--mcp-ui-surface-muted, #f9fafb);font-size:0.75rem;color:var(--mcp-ui-fg-muted, #6b7280)"><kbd style="background-color:var(--mcp-ui-surface-hover, #e5e7eb);padding:1px 4px;border-radius:2px;font-family:inherit;font-size:0.7rem">↑</kbd> <kbd style="background-color:var(--mcp-ui-surface-hover, #e5e7eb);padding:1px 4px;border-radius:2px;font-family:inherit;font-size:0.7rem">↓</kbd><!$><!/><kbd style="background-color:var(--mcp-ui-surface-hover, #e5e7eb);padding:1px 4px;border-radius:2px;font-family:inherit;font-size:0.7rem">Enter</kbd><!$><!/><kbd style="background-color:var(--mcp-ui-surface-hover, #e5e7eb);padding:1px 4px;border-radius:2px;font-family:inherit;font-size:0.7rem">Esc</kbd><!$><!/>`), _tmpl$9 = /* @__PURE__ */ template(`<div role=listbox><!$><!/><!$><!/><!$><!/><!$><!/>`), _tmpl$0 = /* @__PURE__ */ template(`<li role=option style="padding:8px 16px;font-size:0.875rem;transition:background-color 150ms ease">`);
5
5
  function highlightText(text, match) {
6
6
  if (!match || !text) {
7
7
  return text;
@@ -68,10 +68,10 @@ const AutocompleteDropdown = (props) => {
68
68
  left: "0",
69
69
  right: "0",
70
70
  "z-index": "50",
71
- "background-color": "#ffffff",
72
- border: "1px solid #e5e7eb",
71
+ "background-color": "var(--mcp-ui-surface, #ffffff)",
72
+ border: "1px solid var(--mcp-ui-border, #e5e7eb)",
73
73
  "border-radius": "6px",
74
- "box-shadow": "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)",
74
+ "box-shadow": "var(--mcp-ui-shadow, 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06))",
75
75
  "max-height": props.maxHeight || "240px",
76
76
  overflow: "auto",
77
77
  ...positionStyles()
@@ -148,7 +148,7 @@ const AutocompleteDropdown = (props) => {
148
148
  }
149
149
  }));
150
150
  effect((_p$) => {
151
- var _v$4 = isSelected(), _v$5 = isDisabled(), _v$6 = `mcp-autocomplete-option ${isSelected() ? "mcp-autocomplete-option-selected" : ""} ${isDisabled() ? "mcp-autocomplete-option-disabled" : ""}`, _v$7 = isDisabled() ? "not-allowed" : "pointer", _v$8 = isSelected() ? "#eff6ff" : "transparent", _v$9 = isDisabled() ? "#9ca3af" : "#374151";
151
+ var _v$4 = isSelected(), _v$5 = isDisabled(), _v$6 = `mcp-autocomplete-option ${isSelected() ? "mcp-autocomplete-option-selected" : ""} ${isDisabled() ? "mcp-autocomplete-option-disabled" : ""}`, _v$7 = isDisabled() ? "not-allowed" : "pointer", _v$8 = isSelected() ? "var(--mcp-ui-accent-soft, #eff6ff)" : "transparent", _v$9 = isDisabled() ? "var(--mcp-ui-fg-subtle, #9ca3af)" : "var(--mcp-ui-fg, #374151)";
152
152
  _v$4 !== _p$.e && setAttribute(_el$36, "aria-selected", _p$.e = _v$4);
153
153
  _v$5 !== _p$.t && setAttribute(_el$36, "aria-disabled", _p$.t = _v$5);
154
154
  _v$6 !== _p$.a && className(_el$36, _p$.a = _v$6);
@@ -185,7 +185,7 @@ const AutocompleteDropdown = (props) => {
185
185
  }
186
186
  }), _el$35, _co$0);
187
187
  effect((_p$) => {
188
- var _v$ = `mcp-autocomplete-dropdown ${props.class || ""}`, _v$2 = containerStyles(), _v$3 = strings.autocompleteSuggestions;
188
+ var _v$ = `mcp-ui-root mcp-autocomplete-dropdown ${props.class || ""}`, _v$2 = containerStyles(), _v$3 = strings.autocompleteSuggestions;
189
189
  _v$ !== _p$.e && className(_el$1, _p$.e = _v$);
190
190
  _p$.t = style(_el$1, _v$2, _p$.t);
191
191
  _v$3 !== _p$.a && setAttribute(_el$1, "aria-label", _p$.a = _v$3);