@seed-ship/mcp-ui-solid 6.19.0 → 6.19.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 CHANGED
@@ -5,6 +5,19 @@ 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.19.1] - 2026-09-16
9
+
10
+ ### Fixed
11
+
12
+ - **`FeedbackInline` accessible names were hardcoded English.** The two rating
13
+ buttons carried `aria-label="Mark response as useful"` /
14
+ `"Mark response as not useful"` regardless of `MCPUIStringsProvider`, while
15
+ their tooltips already used `strings.feedbackUseful` /
16
+ `strings.feedbackNotUseful`. Both attributes now read the same strings, so
17
+ screen readers get the localized name. Default English accessible names
18
+ therefore become `"Useful"` / `"Not useful"`; the stable hook
19
+ `data-feedback-inline-rating="positive" | "negative"` is unchanged.
20
+
8
21
  ## [6.19.0] - 2026-09-16
9
22
 
10
23
  ### Security
package/README.md CHANGED
@@ -5,6 +5,13 @@ 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.19.1
9
+
10
+ - `FeedbackInline`'s thumb buttons now take their `aria-label` from
11
+ `MCPUIStrings.feedbackUseful` / `feedbackNotUseful` (they were hardcoded
12
+ English while the tooltips were already localized). Defaults: `"Useful"` /
13
+ `"Not useful"`. Target them via `data-feedback-inline-rating`, not the text.
14
+
8
15
  ## What's New in v6.19.0 — sanitization, a11y and packaging
9
16
 
10
17
  - **`sanitizeHtml()` is now the single sanitizer for every sink that carries
@@ -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(`<button type=button class="p-1 rounded hover:bg-green-500/10 text-deposium-slate-500 hover:text-green-500 transition-colors"aria-label="Mark response as useful"data-feedback-inline-rating=positive><svg class="w-3.5 h-3.5"fill=none stroke=currentColor viewBox="0 0 24 24"><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M14 9V5a3 3 0 00-3-3l-4 9v11h11.28a2 2 0 002-1.7l1.38-9a2 2 0 00-2-2.3H14z M3 15v7">`), _tmpl$2 = /* @__PURE__ */ web.template(`<button type=button class="p-1 rounded hover:bg-red-500/10 text-deposium-slate-500 hover:text-red-500 transition-colors"aria-label="Mark response as not useful"data-feedback-inline-rating=negative><svg class="w-3.5 h-3.5"fill=none stroke=currentColor viewBox="0 0 24 24"><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M10 15v4a3 3 0 003 3l4-9V2H5.72a2 2 0 00-2 1.7l-1.38 9a2 2 0 002 2.3H10z M21 4v7">`), _tmpl$3 = /* @__PURE__ */ web.template(`<div>`), _tmpl$4 = /* @__PURE__ */ web.template(`<span class="text-[11px] text-deposium-slate-500">`);
6
+ var _tmpl$ = /* @__PURE__ */ web.template(`<button type=button class="p-1 rounded hover:bg-green-500/10 text-deposium-slate-500 hover:text-green-500 transition-colors"data-feedback-inline-rating=positive><svg class="w-3.5 h-3.5"fill=none stroke=currentColor viewBox="0 0 24 24"><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M14 9V5a3 3 0 00-3-3l-4 9v11h11.28a2 2 0 002-1.7l1.38-9a2 2 0 00-2-2.3H14z M3 15v7">`), _tmpl$2 = /* @__PURE__ */ web.template(`<button type=button class="p-1 rounded hover:bg-red-500/10 text-deposium-slate-500 hover:text-red-500 transition-colors"data-feedback-inline-rating=negative><svg class="w-3.5 h-3.5"fill=none stroke=currentColor viewBox="0 0 24 24"><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M10 15v4a3 3 0 003 3l4-9V2H5.72a2 2 0 00-2 1.7l-1.38 9a2 2 0 002 2.3H10z M21 4v7">`), _tmpl$3 = /* @__PURE__ */ web.template(`<div>`), _tmpl$4 = /* @__PURE__ */ web.template(`<span class="text-[11px] text-deposium-slate-500">`);
7
7
  const FeedbackInline = (props) => {
8
8
  const [rating, setRating] = solidJs.createSignal(null);
9
9
  const strings = MCPUIStringsContext.useMCPUIStrings();
@@ -39,13 +39,29 @@ const FeedbackInline = (props) => {
39
39
  return [(() => {
40
40
  var _el$2 = web.getNextElement(_tmpl$);
41
41
  _el$2.$$click = () => handle("positive");
42
- web.effect(() => web.setAttribute(_el$2, "title", strings.feedbackUseful));
42
+ web.effect((_p$) => {
43
+ var _v$ = strings.feedbackUseful, _v$2 = strings.feedbackUseful;
44
+ _v$ !== _p$.e && web.setAttribute(_el$2, "title", _p$.e = _v$);
45
+ _v$2 !== _p$.t && web.setAttribute(_el$2, "aria-label", _p$.t = _v$2);
46
+ return _p$;
47
+ }, {
48
+ e: void 0,
49
+ t: void 0
50
+ });
43
51
  web.runHydrationEvents();
44
52
  return _el$2;
45
53
  })(), (() => {
46
54
  var _el$3 = web.getNextElement(_tmpl$2);
47
55
  _el$3.$$click = () => handle("negative");
48
- web.effect(() => web.setAttribute(_el$3, "title", strings.feedbackNotUseful));
56
+ web.effect((_p$) => {
57
+ var _v$3 = strings.feedbackNotUseful, _v$4 = strings.feedbackNotUseful;
58
+ _v$3 !== _p$.e && web.setAttribute(_el$3, "title", _p$.e = _v$3);
59
+ _v$4 !== _p$.t && web.setAttribute(_el$3, "aria-label", _p$.t = _v$4);
60
+ return _p$;
61
+ }, {
62
+ e: void 0,
63
+ t: void 0
64
+ });
49
65
  web.runHydrationEvents();
50
66
  return _el$3;
51
67
  })()];
@@ -1 +1 @@
1
- {"version":3,"file":"FeedbackInline.cjs","sources":["../../src/components/FeedbackInline.tsx"],"sourcesContent":["/**\n * FeedbackInline — per-message inline feedback (thumbs up/down)\n *\n * @experimental\n * @since v5.2.0\n *\n * A small, non-blocking per-message feedback primitive. Sits next to an\n * assistant message, captures a rating, calls back to the consumer for\n * persistence. Best-effort by design — no retry UX, no revision UX.\n *\n * ## When to use vs other feedback primitives\n *\n * - **`FeedbackInline`** (this) → per-message thumb-up/down, non-blocking,\n * many can coexist.\n * - **`ChatPrompt` (type=choice)** → modal, one-at-a-time above the input,\n * used when the agent needs a blocking answer.\n * - **`ScratchpadPanel` feedback section** → structured feedback bound to a\n * scratchpad turn, panel-side.\n *\n * ## Persistence is the consumer's job\n *\n * The component flips to \"submitted\" state *optimistically* on click and\n * calls `onSubmit(rating, context)`. Network failures do not revert the UI —\n * feedback is best-effort. If you need stricter semantics (offline retry,\n * revision, ...) wrap this in your own component.\n *\n * @example\n * ```tsx\n * <FeedbackInline\n * messageHash={msg.hash}\n * context={{ intent: msg.intent, confidenceBand: msg.band }}\n * onSubmit={(rating, ctx) =>\n * fetch('/api/feedback', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ message_hash: msg.hash, rating, ...ctx }),\n * })\n * }\n * />\n * ```\n */\n\nimport { Component, Show, createSignal } from 'solid-js'\nimport { useMCPUIStrings } from '../context/MCPUIStringsContext'\n\nexport interface FeedbackInlineContext {\n intent?: string\n confidenceBand?: string\n tags?: string[]\n [key: string]: unknown\n}\n\nexport interface FeedbackInlineProps {\n /** Stable identifier for the message being rated. */\n messageHash?: string\n /**\n * Called on click. Consumer is responsible for persistence (HTTP, store,\n * localStorage). Return value ignored.\n */\n onSubmit: (rating: 'positive' | 'negative', context?: FeedbackInlineContext) => void | Promise<void>\n /** Extra context forwarded to `onSubmit`. */\n context?: FeedbackInlineContext\n /** Ack text shown after positive rating. Defaults to `MCPUIStrings.feedbackPositiveAck` ('Thanks!' in EN). */\n positiveAck?: string\n /** Ack text shown after negative rating. Defaults to `MCPUIStrings.feedbackNegativeAck`. */\n negativeAck?: string\n /** Extra Tailwind classes on the container. */\n class?: string\n}\n\n/**\n * @experimental\n * Per-message inline feedback (thumbs up/down). Non-blocking.\n */\nexport const FeedbackInline: Component<FeedbackInlineProps> = (props) => {\n const [rating, setRating] = createSignal<'positive' | 'negative' | null>(null)\n const strings = useMCPUIStrings()\n\n const handle = (value: 'positive' | 'negative') => {\n if (rating() !== null) return // already submitted, final state\n setRating(value)\n try {\n // Fire-and-forget. If the consumer returns a Promise that rejects,\n // swallow it — feedback is best-effort by design.\n const result = props.onSubmit(value, props.context)\n if (result && typeof (result as Promise<void>).catch === 'function') {\n (result as Promise<void>).catch(() => {\n /* non-blocking */\n })\n }\n } catch {\n /* non-blocking */\n }\n }\n\n return (\n <div class={`flex items-center gap-1 ${props.class ?? ''}`.trim()}>\n <Show\n when={rating() === null}\n fallback={\n <span class=\"text-[11px] text-deposium-slate-500\">\n {rating() === 'positive'\n ? (props.positiveAck ?? strings.feedbackPositiveAck)\n : (props.negativeAck ?? strings.feedbackNegativeAck)}\n </span>\n }\n >\n <button\n type=\"button\"\n onClick={() => handle('positive')}\n class=\"p-1 rounded hover:bg-green-500/10 text-deposium-slate-500 hover:text-green-500 transition-colors\"\n title={strings.feedbackUseful}\n aria-label=\"Mark response as useful\"\n data-feedback-inline-rating=\"positive\"\n >\n <svg class=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M14 9V5a3 3 0 00-3-3l-4 9v11h11.28a2 2 0 002-1.7l1.38-9a2 2 0 00-2-2.3H14z M3 15v7\"\n />\n </svg>\n </button>\n <button\n type=\"button\"\n onClick={() => handle('negative')}\n class=\"p-1 rounded hover:bg-red-500/10 text-deposium-slate-500 hover:text-red-500 transition-colors\"\n title={strings.feedbackNotUseful}\n aria-label=\"Mark response as not useful\"\n data-feedback-inline-rating=\"negative\"\n >\n <svg class=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M10 15v4a3 3 0 003 3l4-9V2H5.72a2 2 0 00-2 1.7l-1.38 9a2 2 0 002 2.3H10z M21 4v7\"\n />\n </svg>\n </button>\n </Show>\n </div>\n )\n}\n"],"names":["FeedbackInline","props","rating","setRating","createSignal","strings","useMCPUIStrings","handle","value","result","onSubmit","context","catch","_el$","_$getNextElement","_tmpl$3","_$insert","_$createComponent","Show","when","fallback","_el$4","_tmpl$4","_c$","_$memo","positiveAck","feedbackPositiveAck","negativeAck","feedbackNegativeAck","children","_el$2","_tmpl$","$$click","_$effect","_$setAttribute","feedbackUseful","_$runHydrationEvents","_el$3","_tmpl$2","feedbackNotUseful","_$className","class","trim","_$delegateEvents"],"mappings":";;;;;;AA0EO,MAAMA,iBAAkDC,CAAAA,UAAU;AACvE,QAAM,CAACC,QAAQC,SAAS,IAAIC,QAAAA,aAA6C,IAAI;AAC7E,QAAMC,UAAUC,oBAAAA,gBAAAA;AAEhB,QAAMC,SAASA,CAACC,UAAmC;AACjD,QAAIN,OAAAA,MAAa,KAAM;AACvBC,cAAUK,KAAK;AACf,QAAI;AAGF,YAAMC,SAASR,MAAMS,SAASF,OAAOP,MAAMU,OAAO;AAClD,UAAIF,UAAU,OAAQA,OAAyBG,UAAU,YAAY;AAClEH,eAAyBG,MAAM,MAAM;AAAA,QACpC,CACD;AAAA,MACH;AAAA,IACF,QAAQ;AAAA,IACN;AAAA,EAEJ;AAEA,UAAA,MAAA;AAAA,QAAAC,OAAAC,IAAAA,eAAAC,OAAA;AAAAC,eAAAH,MAAAI,IAAAA,gBAEKC,cAAI;AAAA,MAAA,IACHC,OAAI;AAAA,eAAEjB,aAAa;AAAA,MAAI;AAAA,MAAA,IACvBkB,WAAQ;AAAA,gBAAA,MAAA;AAAA,cAAAC,QAAAP,IAAAA,eAAAQ,OAAA;AAAAN,cAAAA,OAAAK,QAAA,MAAA;AAAA,gBAAAE,MAAAC,IAAAA,KAAA,MAEHtB,OAAAA,MAAa,UAAU;AAAA,mBAAA,MAAvBqB,QACItB,MAAMwB,eAAepB,QAAQqB,sBAC7BzB,MAAM0B,eAAetB,QAAQuB;AAAAA,UAAoB,IAAA;AAAA,iBAAAP;AAAAA,QAAA,GAAA;AAAA,MAAA;AAAA,MAAA,IAAAQ,WAAA;AAAA,eAAA,EAAA,MAAA;AAAA,cAAAC,QAAAhB,IAAAA,eAAAiB,MAAA;AAAAD,gBAAAE,UAM/C,MAAMzB,OAAO,UAAU;AAAC0B,cAAAA,aAAAC,IAAAA,aAAAJ,OAAA,SAE1BzB,QAAQ8B,cAAc,CAAA;AAAAC,iCAAAA;AAAA,iBAAAN;AAAAA,QAAA,GAAA,IAAA,MAAA;AAAA,cAAAO,QAAAvB,IAAAA,eAAAwB,OAAA;AAAAD,gBAAAL,UAepB,MAAMzB,OAAO,UAAU;AAAC0B,cAAAA,aAAAC,IAAAA,aAAAG,OAAA,SAE1BhC,QAAQkC,iBAAiB,CAAA;AAAAH,iCAAAA;AAAA,iBAAAC;AAAAA,QAAA,IAAA;AAAA,MAAA;AAAA,IAAA,CAAA,CAAA;AAAAJ,QAAAA,OAAA,MAAAO,IAAAA,UAAA3B,MAhC1B,2BAA2BZ,MAAMwC,SAAS,EAAE,GAAGC,KAAAA,CAAM,CAAA;AAAA,WAAA7B;AAAAA,EAAA,GAAA;AAgDrE;AAAC8B,IAAAA,eAAA,CAAA,OAAA,CAAA;;"}
1
+ {"version":3,"file":"FeedbackInline.cjs","sources":["../../src/components/FeedbackInline.tsx"],"sourcesContent":["/**\n * FeedbackInline — per-message inline feedback (thumbs up/down)\n *\n * @experimental\n * @since v5.2.0\n *\n * A small, non-blocking per-message feedback primitive. Sits next to an\n * assistant message, captures a rating, calls back to the consumer for\n * persistence. Best-effort by design — no retry UX, no revision UX.\n *\n * ## When to use vs other feedback primitives\n *\n * - **`FeedbackInline`** (this) → per-message thumb-up/down, non-blocking,\n * many can coexist.\n * - **`ChatPrompt` (type=choice)** → modal, one-at-a-time above the input,\n * used when the agent needs a blocking answer.\n * - **`ScratchpadPanel` feedback section** → structured feedback bound to a\n * scratchpad turn, panel-side.\n *\n * ## Persistence is the consumer's job\n *\n * The component flips to \"submitted\" state *optimistically* on click and\n * calls `onSubmit(rating, context)`. Network failures do not revert the UI —\n * feedback is best-effort. If you need stricter semantics (offline retry,\n * revision, ...) wrap this in your own component.\n *\n * @example\n * ```tsx\n * <FeedbackInline\n * messageHash={msg.hash}\n * context={{ intent: msg.intent, confidenceBand: msg.band }}\n * onSubmit={(rating, ctx) =>\n * fetch('/api/feedback', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ message_hash: msg.hash, rating, ...ctx }),\n * })\n * }\n * />\n * ```\n */\n\nimport { Component, Show, createSignal } from 'solid-js'\nimport { useMCPUIStrings } from '../context/MCPUIStringsContext'\n\nexport interface FeedbackInlineContext {\n intent?: string\n confidenceBand?: string\n tags?: string[]\n [key: string]: unknown\n}\n\nexport interface FeedbackInlineProps {\n /** Stable identifier for the message being rated. */\n messageHash?: string\n /**\n * Called on click. Consumer is responsible for persistence (HTTP, store,\n * localStorage). Return value ignored.\n */\n onSubmit: (rating: 'positive' | 'negative', context?: FeedbackInlineContext) => void | Promise<void>\n /** Extra context forwarded to `onSubmit`. */\n context?: FeedbackInlineContext\n /** Ack text shown after positive rating. Defaults to `MCPUIStrings.feedbackPositiveAck` ('Thanks!' in EN). */\n positiveAck?: string\n /** Ack text shown after negative rating. Defaults to `MCPUIStrings.feedbackNegativeAck`. */\n negativeAck?: string\n /** Extra Tailwind classes on the container. */\n class?: string\n}\n\n/**\n * @experimental\n * Per-message inline feedback (thumbs up/down). Non-blocking.\n */\nexport const FeedbackInline: Component<FeedbackInlineProps> = (props) => {\n const [rating, setRating] = createSignal<'positive' | 'negative' | null>(null)\n const strings = useMCPUIStrings()\n\n const handle = (value: 'positive' | 'negative') => {\n if (rating() !== null) return // already submitted, final state\n setRating(value)\n try {\n // Fire-and-forget. If the consumer returns a Promise that rejects,\n // swallow it — feedback is best-effort by design.\n const result = props.onSubmit(value, props.context)\n if (result && typeof (result as Promise<void>).catch === 'function') {\n (result as Promise<void>).catch(() => {\n /* non-blocking */\n })\n }\n } catch {\n /* non-blocking */\n }\n }\n\n return (\n <div class={`flex items-center gap-1 ${props.class ?? ''}`.trim()}>\n <Show\n when={rating() === null}\n fallback={\n <span class=\"text-[11px] text-deposium-slate-500\">\n {rating() === 'positive'\n ? (props.positiveAck ?? strings.feedbackPositiveAck)\n : (props.negativeAck ?? strings.feedbackNegativeAck)}\n </span>\n }\n >\n <button\n type=\"button\"\n onClick={() => handle('positive')}\n class=\"p-1 rounded hover:bg-green-500/10 text-deposium-slate-500 hover:text-green-500 transition-colors\"\n title={strings.feedbackUseful}\n aria-label={strings.feedbackUseful}\n data-feedback-inline-rating=\"positive\"\n >\n <svg class=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M14 9V5a3 3 0 00-3-3l-4 9v11h11.28a2 2 0 002-1.7l1.38-9a2 2 0 00-2-2.3H14z M3 15v7\"\n />\n </svg>\n </button>\n <button\n type=\"button\"\n onClick={() => handle('negative')}\n class=\"p-1 rounded hover:bg-red-500/10 text-deposium-slate-500 hover:text-red-500 transition-colors\"\n title={strings.feedbackNotUseful}\n aria-label={strings.feedbackNotUseful}\n data-feedback-inline-rating=\"negative\"\n >\n <svg class=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M10 15v4a3 3 0 003 3l4-9V2H5.72a2 2 0 00-2 1.7l-1.38 9a2 2 0 002 2.3H10z M21 4v7\"\n />\n </svg>\n </button>\n </Show>\n </div>\n )\n}\n"],"names":["FeedbackInline","props","rating","setRating","createSignal","strings","useMCPUIStrings","handle","value","result","onSubmit","context","catch","_el$","_$getNextElement","_tmpl$3","_$insert","_$createComponent","Show","when","fallback","_el$4","_tmpl$4","_c$","_$memo","positiveAck","feedbackPositiveAck","negativeAck","feedbackNegativeAck","children","_el$2","_tmpl$","$$click","_$effect","_p$","_v$","feedbackUseful","_v$2","e","_$setAttribute","t","undefined","_$runHydrationEvents","_el$3","_tmpl$2","_v$3","feedbackNotUseful","_v$4","_$className","class","trim","_$delegateEvents"],"mappings":";;;;;;AA0EO,MAAMA,iBAAkDC,CAAAA,UAAU;AACvE,QAAM,CAACC,QAAQC,SAAS,IAAIC,QAAAA,aAA6C,IAAI;AAC7E,QAAMC,UAAUC,oBAAAA,gBAAAA;AAEhB,QAAMC,SAASA,CAACC,UAAmC;AACjD,QAAIN,OAAAA,MAAa,KAAM;AACvBC,cAAUK,KAAK;AACf,QAAI;AAGF,YAAMC,SAASR,MAAMS,SAASF,OAAOP,MAAMU,OAAO;AAClD,UAAIF,UAAU,OAAQA,OAAyBG,UAAU,YAAY;AAClEH,eAAyBG,MAAM,MAAM;AAAA,QACpC,CACD;AAAA,MACH;AAAA,IACF,QAAQ;AAAA,IACN;AAAA,EAEJ;AAEA,UAAA,MAAA;AAAA,QAAAC,OAAAC,IAAAA,eAAAC,OAAA;AAAAC,eAAAH,MAAAI,IAAAA,gBAEKC,cAAI;AAAA,MAAA,IACHC,OAAI;AAAA,eAAEjB,aAAa;AAAA,MAAI;AAAA,MAAA,IACvBkB,WAAQ;AAAA,gBAAA,MAAA;AAAA,cAAAC,QAAAP,IAAAA,eAAAQ,OAAA;AAAAN,cAAAA,OAAAK,QAAA,MAAA;AAAA,gBAAAE,MAAAC,IAAAA,KAAA,MAEHtB,OAAAA,MAAa,UAAU;AAAA,mBAAA,MAAvBqB,QACItB,MAAMwB,eAAepB,QAAQqB,sBAC7BzB,MAAM0B,eAAetB,QAAQuB;AAAAA,UAAoB,IAAA;AAAA,iBAAAP;AAAAA,QAAA,GAAA;AAAA,MAAA;AAAA,MAAA,IAAAQ,WAAA;AAAA,eAAA,EAAA,MAAA;AAAA,cAAAC,QAAAhB,IAAAA,eAAAiB,MAAA;AAAAD,gBAAAE,UAM/C,MAAMzB,OAAO,UAAU;AAAC0B,cAAAA,OAAAC,CAAAA,QAAA;AAAA,gBAAAC,MAE1B9B,QAAQ+B,gBAAcC,OACjBhC,QAAQ+B;AAAcD,oBAAAD,IAAAI,KAAAC,IAAAA,aAAAT,OAAA,SAAAI,IAAAI,IAAAH,GAAA;AAAAE,qBAAAH,IAAAM,KAAAD,IAAAA,aAAAT,OAAA,cAAAI,IAAAM,IAAAH,IAAA;AAAA,mBAAAH;AAAAA,UAAA,GAAA;AAAA,YAAAI,GAAAG;AAAAA,YAAAD,GAAAC;AAAAA,UAAAA,CAAA;AAAAC,iCAAAA;AAAA,iBAAAZ;AAAAA,QAAA,GAAA,IAAA,MAAA;AAAA,cAAAa,QAAA7B,IAAAA,eAAA8B,OAAA;AAAAD,gBAAAX,UAczB,MAAMzB,OAAO,UAAU;AAAC0B,cAAAA,OAAAC,CAAAA,QAAA;AAAA,gBAAAW,OAE1BxC,QAAQyC,mBAAiBC,OACpB1C,QAAQyC;AAAiBD,qBAAAX,IAAAI,KAAAC,IAAAA,aAAAI,OAAA,SAAAT,IAAAI,IAAAO,IAAA;AAAAE,qBAAAb,IAAAM,KAAAD,IAAAA,aAAAI,OAAA,cAAAT,IAAAM,IAAAO,IAAA;AAAA,mBAAAb;AAAAA,UAAA,GAAA;AAAA,YAAAI,GAAAG;AAAAA,YAAAD,GAAAC;AAAAA,UAAAA,CAAA;AAAAC,iCAAAA;AAAA,iBAAAC;AAAAA,QAAA,IAAA;AAAA,MAAA;AAAA,IAAA,CAAA,CAAA;AAAAV,QAAAA,OAAA,MAAAe,IAAAA,UAAAnC,MAjC/B,2BAA2BZ,MAAMgD,SAAS,EAAE,GAAGC,KAAAA,CAAM,CAAA;AAAA,WAAArC;AAAAA,EAAA,GAAA;AAgDrE;AAACsC,IAAAA,eAAA,CAAA,OAAA,CAAA;;"}
@@ -1,7 +1,7 @@
1
1
  import { getNextElement, insert, createComponent, effect, setAttribute, runHydrationEvents, memo, className, template, delegateEvents } from "solid-js/web";
2
2
  import { createSignal, Show } from "solid-js";
3
3
  import { useMCPUIStrings } from "../context/MCPUIStringsContext.js";
4
- var _tmpl$ = /* @__PURE__ */ template(`<button type=button class="p-1 rounded hover:bg-green-500/10 text-deposium-slate-500 hover:text-green-500 transition-colors"aria-label="Mark response as useful"data-feedback-inline-rating=positive><svg class="w-3.5 h-3.5"fill=none stroke=currentColor viewBox="0 0 24 24"><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M14 9V5a3 3 0 00-3-3l-4 9v11h11.28a2 2 0 002-1.7l1.38-9a2 2 0 00-2-2.3H14z M3 15v7">`), _tmpl$2 = /* @__PURE__ */ template(`<button type=button class="p-1 rounded hover:bg-red-500/10 text-deposium-slate-500 hover:text-red-500 transition-colors"aria-label="Mark response as not useful"data-feedback-inline-rating=negative><svg class="w-3.5 h-3.5"fill=none stroke=currentColor viewBox="0 0 24 24"><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M10 15v4a3 3 0 003 3l4-9V2H5.72a2 2 0 00-2 1.7l-1.38 9a2 2 0 002 2.3H10z M21 4v7">`), _tmpl$3 = /* @__PURE__ */ template(`<div>`), _tmpl$4 = /* @__PURE__ */ template(`<span class="text-[11px] text-deposium-slate-500">`);
4
+ var _tmpl$ = /* @__PURE__ */ template(`<button type=button class="p-1 rounded hover:bg-green-500/10 text-deposium-slate-500 hover:text-green-500 transition-colors"data-feedback-inline-rating=positive><svg class="w-3.5 h-3.5"fill=none stroke=currentColor viewBox="0 0 24 24"><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M14 9V5a3 3 0 00-3-3l-4 9v11h11.28a2 2 0 002-1.7l1.38-9a2 2 0 00-2-2.3H14z M3 15v7">`), _tmpl$2 = /* @__PURE__ */ template(`<button type=button class="p-1 rounded hover:bg-red-500/10 text-deposium-slate-500 hover:text-red-500 transition-colors"data-feedback-inline-rating=negative><svg class="w-3.5 h-3.5"fill=none stroke=currentColor viewBox="0 0 24 24"><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M10 15v4a3 3 0 003 3l4-9V2H5.72a2 2 0 00-2 1.7l-1.38 9a2 2 0 002 2.3H10z M21 4v7">`), _tmpl$3 = /* @__PURE__ */ template(`<div>`), _tmpl$4 = /* @__PURE__ */ template(`<span class="text-[11px] text-deposium-slate-500">`);
5
5
  const FeedbackInline = (props) => {
6
6
  const [rating, setRating] = createSignal(null);
7
7
  const strings = useMCPUIStrings();
@@ -37,13 +37,29 @@ const FeedbackInline = (props) => {
37
37
  return [(() => {
38
38
  var _el$2 = getNextElement(_tmpl$);
39
39
  _el$2.$$click = () => handle("positive");
40
- effect(() => setAttribute(_el$2, "title", strings.feedbackUseful));
40
+ effect((_p$) => {
41
+ var _v$ = strings.feedbackUseful, _v$2 = strings.feedbackUseful;
42
+ _v$ !== _p$.e && setAttribute(_el$2, "title", _p$.e = _v$);
43
+ _v$2 !== _p$.t && setAttribute(_el$2, "aria-label", _p$.t = _v$2);
44
+ return _p$;
45
+ }, {
46
+ e: void 0,
47
+ t: void 0
48
+ });
41
49
  runHydrationEvents();
42
50
  return _el$2;
43
51
  })(), (() => {
44
52
  var _el$3 = getNextElement(_tmpl$2);
45
53
  _el$3.$$click = () => handle("negative");
46
- effect(() => setAttribute(_el$3, "title", strings.feedbackNotUseful));
54
+ effect((_p$) => {
55
+ var _v$3 = strings.feedbackNotUseful, _v$4 = strings.feedbackNotUseful;
56
+ _v$3 !== _p$.e && setAttribute(_el$3, "title", _p$.e = _v$3);
57
+ _v$4 !== _p$.t && setAttribute(_el$3, "aria-label", _p$.t = _v$4);
58
+ return _p$;
59
+ }, {
60
+ e: void 0,
61
+ t: void 0
62
+ });
47
63
  runHydrationEvents();
48
64
  return _el$3;
49
65
  })()];
@@ -1 +1 @@
1
- {"version":3,"file":"FeedbackInline.js","sources":["../../src/components/FeedbackInline.tsx"],"sourcesContent":["/**\n * FeedbackInline — per-message inline feedback (thumbs up/down)\n *\n * @experimental\n * @since v5.2.0\n *\n * A small, non-blocking per-message feedback primitive. Sits next to an\n * assistant message, captures a rating, calls back to the consumer for\n * persistence. Best-effort by design — no retry UX, no revision UX.\n *\n * ## When to use vs other feedback primitives\n *\n * - **`FeedbackInline`** (this) → per-message thumb-up/down, non-blocking,\n * many can coexist.\n * - **`ChatPrompt` (type=choice)** → modal, one-at-a-time above the input,\n * used when the agent needs a blocking answer.\n * - **`ScratchpadPanel` feedback section** → structured feedback bound to a\n * scratchpad turn, panel-side.\n *\n * ## Persistence is the consumer's job\n *\n * The component flips to \"submitted\" state *optimistically* on click and\n * calls `onSubmit(rating, context)`. Network failures do not revert the UI —\n * feedback is best-effort. If you need stricter semantics (offline retry,\n * revision, ...) wrap this in your own component.\n *\n * @example\n * ```tsx\n * <FeedbackInline\n * messageHash={msg.hash}\n * context={{ intent: msg.intent, confidenceBand: msg.band }}\n * onSubmit={(rating, ctx) =>\n * fetch('/api/feedback', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ message_hash: msg.hash, rating, ...ctx }),\n * })\n * }\n * />\n * ```\n */\n\nimport { Component, Show, createSignal } from 'solid-js'\nimport { useMCPUIStrings } from '../context/MCPUIStringsContext'\n\nexport interface FeedbackInlineContext {\n intent?: string\n confidenceBand?: string\n tags?: string[]\n [key: string]: unknown\n}\n\nexport interface FeedbackInlineProps {\n /** Stable identifier for the message being rated. */\n messageHash?: string\n /**\n * Called on click. Consumer is responsible for persistence (HTTP, store,\n * localStorage). Return value ignored.\n */\n onSubmit: (rating: 'positive' | 'negative', context?: FeedbackInlineContext) => void | Promise<void>\n /** Extra context forwarded to `onSubmit`. */\n context?: FeedbackInlineContext\n /** Ack text shown after positive rating. Defaults to `MCPUIStrings.feedbackPositiveAck` ('Thanks!' in EN). */\n positiveAck?: string\n /** Ack text shown after negative rating. Defaults to `MCPUIStrings.feedbackNegativeAck`. */\n negativeAck?: string\n /** Extra Tailwind classes on the container. */\n class?: string\n}\n\n/**\n * @experimental\n * Per-message inline feedback (thumbs up/down). Non-blocking.\n */\nexport const FeedbackInline: Component<FeedbackInlineProps> = (props) => {\n const [rating, setRating] = createSignal<'positive' | 'negative' | null>(null)\n const strings = useMCPUIStrings()\n\n const handle = (value: 'positive' | 'negative') => {\n if (rating() !== null) return // already submitted, final state\n setRating(value)\n try {\n // Fire-and-forget. If the consumer returns a Promise that rejects,\n // swallow it — feedback is best-effort by design.\n const result = props.onSubmit(value, props.context)\n if (result && typeof (result as Promise<void>).catch === 'function') {\n (result as Promise<void>).catch(() => {\n /* non-blocking */\n })\n }\n } catch {\n /* non-blocking */\n }\n }\n\n return (\n <div class={`flex items-center gap-1 ${props.class ?? ''}`.trim()}>\n <Show\n when={rating() === null}\n fallback={\n <span class=\"text-[11px] text-deposium-slate-500\">\n {rating() === 'positive'\n ? (props.positiveAck ?? strings.feedbackPositiveAck)\n : (props.negativeAck ?? strings.feedbackNegativeAck)}\n </span>\n }\n >\n <button\n type=\"button\"\n onClick={() => handle('positive')}\n class=\"p-1 rounded hover:bg-green-500/10 text-deposium-slate-500 hover:text-green-500 transition-colors\"\n title={strings.feedbackUseful}\n aria-label=\"Mark response as useful\"\n data-feedback-inline-rating=\"positive\"\n >\n <svg class=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M14 9V5a3 3 0 00-3-3l-4 9v11h11.28a2 2 0 002-1.7l1.38-9a2 2 0 00-2-2.3H14z M3 15v7\"\n />\n </svg>\n </button>\n <button\n type=\"button\"\n onClick={() => handle('negative')}\n class=\"p-1 rounded hover:bg-red-500/10 text-deposium-slate-500 hover:text-red-500 transition-colors\"\n title={strings.feedbackNotUseful}\n aria-label=\"Mark response as not useful\"\n data-feedback-inline-rating=\"negative\"\n >\n <svg class=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M10 15v4a3 3 0 003 3l4-9V2H5.72a2 2 0 00-2 1.7l-1.38 9a2 2 0 002 2.3H10z M21 4v7\"\n />\n </svg>\n </button>\n </Show>\n </div>\n )\n}\n"],"names":["FeedbackInline","props","rating","setRating","createSignal","strings","useMCPUIStrings","handle","value","result","onSubmit","context","catch","_el$","_$getNextElement","_tmpl$3","_$insert","_$createComponent","Show","when","fallback","_el$4","_tmpl$4","_c$","_$memo","positiveAck","feedbackPositiveAck","negativeAck","feedbackNegativeAck","children","_el$2","_tmpl$","$$click","_$effect","_$setAttribute","feedbackUseful","_$runHydrationEvents","_el$3","_tmpl$2","feedbackNotUseful","_$className","class","trim","_$delegateEvents"],"mappings":";;;;AA0EO,MAAMA,iBAAkDC,CAAAA,UAAU;AACvE,QAAM,CAACC,QAAQC,SAAS,IAAIC,aAA6C,IAAI;AAC7E,QAAMC,UAAUC,gBAAAA;AAEhB,QAAMC,SAASA,CAACC,UAAmC;AACjD,QAAIN,OAAAA,MAAa,KAAM;AACvBC,cAAUK,KAAK;AACf,QAAI;AAGF,YAAMC,SAASR,MAAMS,SAASF,OAAOP,MAAMU,OAAO;AAClD,UAAIF,UAAU,OAAQA,OAAyBG,UAAU,YAAY;AAClEH,eAAyBG,MAAM,MAAM;AAAA,QACpC,CACD;AAAA,MACH;AAAA,IACF,QAAQ;AAAA,IACN;AAAA,EAEJ;AAEA,UAAA,MAAA;AAAA,QAAAC,OAAAC,eAAAC,OAAA;AAAAC,WAAAH,MAAAI,gBAEKC,MAAI;AAAA,MAAA,IACHC,OAAI;AAAA,eAAEjB,aAAa;AAAA,MAAI;AAAA,MAAA,IACvBkB,WAAQ;AAAA,gBAAA,MAAA;AAAA,cAAAC,QAAAP,eAAAQ,OAAA;AAAAN,iBAAAK,QAAA,MAAA;AAAA,gBAAAE,MAAAC,KAAA,MAEHtB,OAAAA,MAAa,UAAU;AAAA,mBAAA,MAAvBqB,QACItB,MAAMwB,eAAepB,QAAQqB,sBAC7BzB,MAAM0B,eAAetB,QAAQuB;AAAAA,UAAoB,IAAA;AAAA,iBAAAP;AAAAA,QAAA,GAAA;AAAA,MAAA;AAAA,MAAA,IAAAQ,WAAA;AAAA,eAAA,EAAA,MAAA;AAAA,cAAAC,QAAAhB,eAAAiB,MAAA;AAAAD,gBAAAE,UAM/C,MAAMzB,OAAO,UAAU;AAAC0B,uBAAAC,aAAAJ,OAAA,SAE1BzB,QAAQ8B,cAAc,CAAA;AAAAC,6BAAAA;AAAA,iBAAAN;AAAAA,QAAA,GAAA,IAAA,MAAA;AAAA,cAAAO,QAAAvB,eAAAwB,OAAA;AAAAD,gBAAAL,UAepB,MAAMzB,OAAO,UAAU;AAAC0B,uBAAAC,aAAAG,OAAA,SAE1BhC,QAAQkC,iBAAiB,CAAA;AAAAH,6BAAAA;AAAA,iBAAAC;AAAAA,QAAA,IAAA;AAAA,MAAA;AAAA,IAAA,CAAA,CAAA;AAAAJ,WAAA,MAAAO,UAAA3B,MAhC1B,2BAA2BZ,MAAMwC,SAAS,EAAE,GAAGC,KAAAA,CAAM,CAAA;AAAA,WAAA7B;AAAAA,EAAA,GAAA;AAgDrE;AAAC8B,eAAA,CAAA,OAAA,CAAA;"}
1
+ {"version":3,"file":"FeedbackInline.js","sources":["../../src/components/FeedbackInline.tsx"],"sourcesContent":["/**\n * FeedbackInline — per-message inline feedback (thumbs up/down)\n *\n * @experimental\n * @since v5.2.0\n *\n * A small, non-blocking per-message feedback primitive. Sits next to an\n * assistant message, captures a rating, calls back to the consumer for\n * persistence. Best-effort by design — no retry UX, no revision UX.\n *\n * ## When to use vs other feedback primitives\n *\n * - **`FeedbackInline`** (this) → per-message thumb-up/down, non-blocking,\n * many can coexist.\n * - **`ChatPrompt` (type=choice)** → modal, one-at-a-time above the input,\n * used when the agent needs a blocking answer.\n * - **`ScratchpadPanel` feedback section** → structured feedback bound to a\n * scratchpad turn, panel-side.\n *\n * ## Persistence is the consumer's job\n *\n * The component flips to \"submitted\" state *optimistically* on click and\n * calls `onSubmit(rating, context)`. Network failures do not revert the UI —\n * feedback is best-effort. If you need stricter semantics (offline retry,\n * revision, ...) wrap this in your own component.\n *\n * @example\n * ```tsx\n * <FeedbackInline\n * messageHash={msg.hash}\n * context={{ intent: msg.intent, confidenceBand: msg.band }}\n * onSubmit={(rating, ctx) =>\n * fetch('/api/feedback', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ message_hash: msg.hash, rating, ...ctx }),\n * })\n * }\n * />\n * ```\n */\n\nimport { Component, Show, createSignal } from 'solid-js'\nimport { useMCPUIStrings } from '../context/MCPUIStringsContext'\n\nexport interface FeedbackInlineContext {\n intent?: string\n confidenceBand?: string\n tags?: string[]\n [key: string]: unknown\n}\n\nexport interface FeedbackInlineProps {\n /** Stable identifier for the message being rated. */\n messageHash?: string\n /**\n * Called on click. Consumer is responsible for persistence (HTTP, store,\n * localStorage). Return value ignored.\n */\n onSubmit: (rating: 'positive' | 'negative', context?: FeedbackInlineContext) => void | Promise<void>\n /** Extra context forwarded to `onSubmit`. */\n context?: FeedbackInlineContext\n /** Ack text shown after positive rating. Defaults to `MCPUIStrings.feedbackPositiveAck` ('Thanks!' in EN). */\n positiveAck?: string\n /** Ack text shown after negative rating. Defaults to `MCPUIStrings.feedbackNegativeAck`. */\n negativeAck?: string\n /** Extra Tailwind classes on the container. */\n class?: string\n}\n\n/**\n * @experimental\n * Per-message inline feedback (thumbs up/down). Non-blocking.\n */\nexport const FeedbackInline: Component<FeedbackInlineProps> = (props) => {\n const [rating, setRating] = createSignal<'positive' | 'negative' | null>(null)\n const strings = useMCPUIStrings()\n\n const handle = (value: 'positive' | 'negative') => {\n if (rating() !== null) return // already submitted, final state\n setRating(value)\n try {\n // Fire-and-forget. If the consumer returns a Promise that rejects,\n // swallow it — feedback is best-effort by design.\n const result = props.onSubmit(value, props.context)\n if (result && typeof (result as Promise<void>).catch === 'function') {\n (result as Promise<void>).catch(() => {\n /* non-blocking */\n })\n }\n } catch {\n /* non-blocking */\n }\n }\n\n return (\n <div class={`flex items-center gap-1 ${props.class ?? ''}`.trim()}>\n <Show\n when={rating() === null}\n fallback={\n <span class=\"text-[11px] text-deposium-slate-500\">\n {rating() === 'positive'\n ? (props.positiveAck ?? strings.feedbackPositiveAck)\n : (props.negativeAck ?? strings.feedbackNegativeAck)}\n </span>\n }\n >\n <button\n type=\"button\"\n onClick={() => handle('positive')}\n class=\"p-1 rounded hover:bg-green-500/10 text-deposium-slate-500 hover:text-green-500 transition-colors\"\n title={strings.feedbackUseful}\n aria-label={strings.feedbackUseful}\n data-feedback-inline-rating=\"positive\"\n >\n <svg class=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M14 9V5a3 3 0 00-3-3l-4 9v11h11.28a2 2 0 002-1.7l1.38-9a2 2 0 00-2-2.3H14z M3 15v7\"\n />\n </svg>\n </button>\n <button\n type=\"button\"\n onClick={() => handle('negative')}\n class=\"p-1 rounded hover:bg-red-500/10 text-deposium-slate-500 hover:text-red-500 transition-colors\"\n title={strings.feedbackNotUseful}\n aria-label={strings.feedbackNotUseful}\n data-feedback-inline-rating=\"negative\"\n >\n <svg class=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M10 15v4a3 3 0 003 3l4-9V2H5.72a2 2 0 00-2 1.7l-1.38 9a2 2 0 002 2.3H10z M21 4v7\"\n />\n </svg>\n </button>\n </Show>\n </div>\n )\n}\n"],"names":["FeedbackInline","props","rating","setRating","createSignal","strings","useMCPUIStrings","handle","value","result","onSubmit","context","catch","_el$","_$getNextElement","_tmpl$3","_$insert","_$createComponent","Show","when","fallback","_el$4","_tmpl$4","_c$","_$memo","positiveAck","feedbackPositiveAck","negativeAck","feedbackNegativeAck","children","_el$2","_tmpl$","$$click","_$effect","_p$","_v$","feedbackUseful","_v$2","e","_$setAttribute","t","undefined","_$runHydrationEvents","_el$3","_tmpl$2","_v$3","feedbackNotUseful","_v$4","_$className","class","trim","_$delegateEvents"],"mappings":";;;;AA0EO,MAAMA,iBAAkDC,CAAAA,UAAU;AACvE,QAAM,CAACC,QAAQC,SAAS,IAAIC,aAA6C,IAAI;AAC7E,QAAMC,UAAUC,gBAAAA;AAEhB,QAAMC,SAASA,CAACC,UAAmC;AACjD,QAAIN,OAAAA,MAAa,KAAM;AACvBC,cAAUK,KAAK;AACf,QAAI;AAGF,YAAMC,SAASR,MAAMS,SAASF,OAAOP,MAAMU,OAAO;AAClD,UAAIF,UAAU,OAAQA,OAAyBG,UAAU,YAAY;AAClEH,eAAyBG,MAAM,MAAM;AAAA,QACpC,CACD;AAAA,MACH;AAAA,IACF,QAAQ;AAAA,IACN;AAAA,EAEJ;AAEA,UAAA,MAAA;AAAA,QAAAC,OAAAC,eAAAC,OAAA;AAAAC,WAAAH,MAAAI,gBAEKC,MAAI;AAAA,MAAA,IACHC,OAAI;AAAA,eAAEjB,aAAa;AAAA,MAAI;AAAA,MAAA,IACvBkB,WAAQ;AAAA,gBAAA,MAAA;AAAA,cAAAC,QAAAP,eAAAQ,OAAA;AAAAN,iBAAAK,QAAA,MAAA;AAAA,gBAAAE,MAAAC,KAAA,MAEHtB,OAAAA,MAAa,UAAU;AAAA,mBAAA,MAAvBqB,QACItB,MAAMwB,eAAepB,QAAQqB,sBAC7BzB,MAAM0B,eAAetB,QAAQuB;AAAAA,UAAoB,IAAA;AAAA,iBAAAP;AAAAA,QAAA,GAAA;AAAA,MAAA;AAAA,MAAA,IAAAQ,WAAA;AAAA,eAAA,EAAA,MAAA;AAAA,cAAAC,QAAAhB,eAAAiB,MAAA;AAAAD,gBAAAE,UAM/C,MAAMzB,OAAO,UAAU;AAAC0B,iBAAAC,CAAAA,QAAA;AAAA,gBAAAC,MAE1B9B,QAAQ+B,gBAAcC,OACjBhC,QAAQ+B;AAAcD,oBAAAD,IAAAI,KAAAC,aAAAT,OAAA,SAAAI,IAAAI,IAAAH,GAAA;AAAAE,qBAAAH,IAAAM,KAAAD,aAAAT,OAAA,cAAAI,IAAAM,IAAAH,IAAA;AAAA,mBAAAH;AAAAA,UAAA,GAAA;AAAA,YAAAI,GAAAG;AAAAA,YAAAD,GAAAC;AAAAA,UAAAA,CAAA;AAAAC,6BAAAA;AAAA,iBAAAZ;AAAAA,QAAA,GAAA,IAAA,MAAA;AAAA,cAAAa,QAAA7B,eAAA8B,OAAA;AAAAD,gBAAAX,UAczB,MAAMzB,OAAO,UAAU;AAAC0B,iBAAAC,CAAAA,QAAA;AAAA,gBAAAW,OAE1BxC,QAAQyC,mBAAiBC,OACpB1C,QAAQyC;AAAiBD,qBAAAX,IAAAI,KAAAC,aAAAI,OAAA,SAAAT,IAAAI,IAAAO,IAAA;AAAAE,qBAAAb,IAAAM,KAAAD,aAAAI,OAAA,cAAAT,IAAAM,IAAAO,IAAA;AAAA,mBAAAb;AAAAA,UAAA,GAAA;AAAA,YAAAI,GAAAG;AAAAA,YAAAD,GAAAC;AAAAA,UAAAA,CAAA;AAAAC,6BAAAA;AAAA,iBAAAC;AAAAA,QAAA,IAAA;AAAA,MAAA;AAAA,IAAA,CAAA,CAAA;AAAAV,WAAA,MAAAe,UAAAnC,MAjC/B,2BAA2BZ,MAAMgD,SAAS,EAAE,GAAGC,KAAAA,CAAM,CAAA;AAAA,WAAArC;AAAAA,EAAA,GAAA;AAgDrE;AAACsC,eAAA,CAAA,OAAA,CAAA;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seed-ship/mcp-ui-solid",
3
- "version": "6.19.0",
3
+ "version": "6.19.1",
4
4
  "description": "SolidJS components for rendering MCP-generated UI resources",
5
5
  "type": "module",
6
6
  "files": [
@@ -110,7 +110,7 @@ export const FeedbackInline: Component<FeedbackInlineProps> = (props) => {
110
110
  onClick={() => handle('positive')}
111
111
  class="p-1 rounded hover:bg-green-500/10 text-deposium-slate-500 hover:text-green-500 transition-colors"
112
112
  title={strings.feedbackUseful}
113
- aria-label="Mark response as useful"
113
+ aria-label={strings.feedbackUseful}
114
114
  data-feedback-inline-rating="positive"
115
115
  >
116
116
  <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -127,7 +127,7 @@ export const FeedbackInline: Component<FeedbackInlineProps> = (props) => {
127
127
  onClick={() => handle('negative')}
128
128
  class="p-1 rounded hover:bg-red-500/10 text-deposium-slate-500 hover:text-red-500 transition-colors"
129
129
  title={strings.feedbackNotUseful}
130
- aria-label="Mark response as not useful"
130
+ aria-label={strings.feedbackNotUseful}
131
131
  data-feedback-inline-rating="negative"
132
132
  >
133
133
  <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">