@handled-ai/design-system 0.18.31 → 0.18.33

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.
@@ -53,7 +53,7 @@ function DraftFeedbackInline({
53
53
  }, [thumbState, selectedPills, detailText, onDiscardRequest]);
54
54
  if (noted) {
55
55
  return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 py-1 animate-in fade-in slide-in-from-top-1 duration-200", children: [
56
- /* @__PURE__ */ jsx(Check, { className: "w-3.5 h-3.5 text-emerald-500" }),
56
+ /* @__PURE__ */ jsx(Check, { className: "w-3.5 h-3.5 text-foreground" }),
57
57
  /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "Feedback recorded" })
58
58
  ] });
59
59
  }
@@ -63,7 +63,7 @@ function DraftFeedbackInline({
63
63
  /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-indigo-600 dark:text-indigo-400", children: "Regenerating draft..." })
64
64
  ] }) });
65
65
  }
66
- return /* @__PURE__ */ jsxs("div", { className: "space-y-0", children: [
66
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
67
67
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
68
68
  /* @__PURE__ */ jsx("span", { className: "text-sm text-foreground font-medium", children: "How's this draft?" }),
69
69
  /* @__PURE__ */ jsxs("div", { className: "flex gap-1", children: [
@@ -75,8 +75,8 @@ function DraftFeedbackInline({
75
75
  setSelectedPills([]);
76
76
  setDetailText("");
77
77
  },
78
- className: `p-1.5 rounded transition-colors ${thumbState === "up" ? "bg-emerald-100 text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400" : "hover:bg-muted text-muted-foreground hover:text-foreground"}`,
79
- children: /* @__PURE__ */ jsx(ThumbsUp, { className: "w-4 h-4", fill: thumbState === "up" ? "currentColor" : "none" })
78
+ className: `p-1.5 rounded transition-colors ${thumbState === "up" ? "bg-muted text-foreground" : "hover:bg-muted text-muted-foreground hover:text-foreground"}`,
79
+ children: /* @__PURE__ */ jsx(ThumbsUp, { className: "w-4 h-4" })
80
80
  }
81
81
  ),
82
82
  /* @__PURE__ */ jsx(
@@ -87,20 +87,20 @@ function DraftFeedbackInline({
87
87
  setSelectedPills([]);
88
88
  setDetailText("");
89
89
  },
90
- className: `p-1.5 rounded transition-colors ${thumbState === "down" ? "bg-red-100 text-red-600 dark:bg-red-900/30 dark:text-red-400" : "hover:bg-muted text-muted-foreground hover:text-foreground"}`,
91
- children: /* @__PURE__ */ jsx(ThumbsDown, { className: "w-4 h-4", fill: thumbState === "down" ? "currentColor" : "none" })
90
+ className: `p-1.5 rounded transition-colors ${thumbState === "down" ? "bg-red-50 text-red-600 dark:bg-red-950/30 dark:text-red-400" : "hover:bg-muted text-muted-foreground hover:text-foreground"}`,
91
+ children: /* @__PURE__ */ jsx(ThumbsDown, { className: "w-4 h-4" })
92
92
  }
93
93
  )
94
94
  ] })
95
95
  ] }),
96
- thumbState && /* @__PURE__ */ jsxs("div", { className: "pt-3 space-y-3 animate-in fade-in slide-in-from-top-2 duration-200", children: [
96
+ thumbState && /* @__PURE__ */ jsxs("div", { className: "pt-2 space-y-2.5 animate-in fade-in slide-in-from-top-2 duration-200", children: [
97
97
  /* @__PURE__ */ jsxs("div", { children: [
98
98
  /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground mb-2 block font-medium", children: thumbState === "up" ? "What worked well?" : "What needs improvement?" }),
99
- /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: (thumbState === "up" ? positivePills : negativePills).map((pill) => /* @__PURE__ */ jsx(
99
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: (thumbState === "up" ? positivePills : negativePills).map((pill) => /* @__PURE__ */ jsx(
100
100
  "button",
101
101
  {
102
102
  onClick: () => togglePill(pill),
103
- className: `px-2.5 py-1 rounded-full text-[11px] font-medium border transition-colors ${selectedPills.includes(pill) ? thumbState === "up" ? "bg-emerald-100 text-emerald-700 border-emerald-200 dark:bg-emerald-900/30 dark:text-emerald-300 dark:border-emerald-800" : "bg-red-100 text-red-700 border-red-200 dark:bg-red-900/30 dark:text-red-300 dark:border-red-800" : "bg-background text-muted-foreground border-border hover:bg-muted/50 hover:text-foreground"}`,
103
+ className: `px-3 py-1.5 rounded-full text-[11px] font-medium border transition-colors ${selectedPills.includes(pill) ? thumbState === "up" ? "bg-muted text-foreground border-border" : "bg-red-50 text-red-700 border-red-200 dark:bg-red-950/30 dark:text-red-300 dark:border-red-800" : "bg-background text-muted-foreground border-border hover:bg-muted/50 hover:text-foreground"}`,
104
104
  children: pill
105
105
  },
106
106
  pill
@@ -115,7 +115,7 @@ function DraftFeedbackInline({
115
115
  className: "w-full text-xs bg-background border border-border rounded-md px-2.5 py-2 text-foreground placeholder:text-muted-foreground/50 focus:outline-none focus:ring-1 focus:ring-indigo-500/50 focus:border-indigo-500/50 resize-none min-h-[60px]"
116
116
  }
117
117
  ),
118
- /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2 pt-1", children: thumbState === "down" ? /* @__PURE__ */ jsxs(Fragment, { children: [
118
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2.5 pt-2", children: thumbState === "down" ? /* @__PURE__ */ jsxs(Fragment, { children: [
119
119
  /* @__PURE__ */ jsxs(
120
120
  "button",
121
121
  {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/draft-feedback-inline.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport {\n ThumbsUp,\n ThumbsDown,\n Check,\n RefreshCw,\n} from \"lucide-react\"\n\n// ---------------------------------------------------------------------------\n// DraftFeedbackInline\n// ---------------------------------------------------------------------------\n\nconst positivePills = [\"Tone\", \"Personalization\", \"Length\", \"CTA\", \"Other\"]\nconst negativePills = [\"Too formal\", \"Too casual\", \"Too long\", \"Missing context\", \"Wrong angle\", \"Factual error\", \"Other\"]\n\nexport interface DraftFeedbackInlineProps {\n initialDirection?: 'up' | 'down' | null\n onRegenerateRequest?: (pills: string[], detail: string) => void\n onSubmitFeedback?: (type: \"up\" | \"down\", pills: string[], detail: string) => void\n onDiscardRequest?: (pills: string[], detail: string) => void\n}\n\nexport function DraftFeedbackInline({\n initialDirection,\n onRegenerateRequest,\n onSubmitFeedback,\n onDiscardRequest,\n}: DraftFeedbackInlineProps) {\n const [thumbState, setThumbState] = React.useState<\"up\" | \"down\" | null>(initialDirection ?? null)\n const [selectedPills, setSelectedPills] = React.useState<string[]>([])\n const [detailText, setDetailText] = React.useState(\"\")\n const [noted, setNoted] = React.useState(false)\n const [regenerated, setRegenerated] = React.useState(false)\n\n const togglePill = React.useCallback((pill: string) => {\n setSelectedPills((prev) => (prev.includes(pill) ? prev.filter((p) => p !== pill) : [...prev, pill]))\n }, [])\n\n const handleSubmit = React.useCallback(() => {\n if (!thumbState) return\n onSubmitFeedback?.(thumbState, selectedPills, detailText)\n setNoted(true)\n setTimeout(() => {\n setThumbState(null)\n setSelectedPills([])\n setDetailText(\"\")\n setNoted(false)\n }, 3000)\n }, [thumbState, selectedPills, detailText, onSubmitFeedback])\n\n const handleRegenerate = React.useCallback(() => {\n if (!thumbState) return\n onRegenerateRequest?.(selectedPills, detailText)\n setRegenerated(true)\n setTimeout(() => {\n setThumbState(null)\n setSelectedPills([])\n setDetailText(\"\")\n setRegenerated(false)\n }, 3000)\n }, [thumbState, selectedPills, detailText, onRegenerateRequest])\n\n const handleDiscard = React.useCallback(() => {\n if (!thumbState) return\n onDiscardRequest?.(selectedPills, detailText)\n }, [thumbState, selectedPills, detailText, onDiscardRequest])\n\n if (noted) {\n return (\n <div className=\"flex items-center gap-1.5 py-1 animate-in fade-in slide-in-from-top-1 duration-200\">\n <Check className=\"w-3.5 h-3.5 text-emerald-500\" />\n <span className=\"text-xs text-muted-foreground\">Feedback recorded</span>\n </div>\n )\n }\n\n if (regenerated) {\n return (\n <div className=\"py-2 animate-in fade-in slide-in-from-top-1 duration-200\">\n <div className=\"flex items-center gap-2 px-3 py-2 rounded-md bg-indigo-50 dark:bg-indigo-950/30 border border-indigo-200 dark:border-indigo-800\">\n <RefreshCw className=\"w-3 h-3 text-indigo-500 animate-spin\" />\n <span className=\"text-xs font-medium text-indigo-600 dark:text-indigo-400\">Regenerating draft...</span>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"space-y-0\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-foreground font-medium\">How&apos;s this draft?</span>\n <div className=\"flex gap-1\">\n <button\n onClick={() => {\n setThumbState(thumbState === \"up\" ? null : \"up\")\n setSelectedPills([])\n setDetailText(\"\")\n }}\n className={`p-1.5 rounded transition-colors ${\n thumbState === \"up\"\n ? \"bg-emerald-100 text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400\"\n : \"hover:bg-muted text-muted-foreground hover:text-foreground\"\n }`}\n >\n <ThumbsUp className=\"w-4 h-4\" fill={thumbState === \"up\" ? \"currentColor\" : \"none\"} />\n </button>\n <button\n onClick={() => {\n setThumbState(thumbState === \"down\" ? null : \"down\")\n setSelectedPills([])\n setDetailText(\"\")\n }}\n className={`p-1.5 rounded transition-colors ${\n thumbState === \"down\"\n ? \"bg-red-100 text-red-600 dark:bg-red-900/30 dark:text-red-400\"\n : \"hover:bg-muted text-muted-foreground hover:text-foreground\"\n }`}\n >\n <ThumbsDown className=\"w-4 h-4\" fill={thumbState === \"down\" ? \"currentColor\" : \"none\"} />\n </button>\n </div>\n </div>\n\n {thumbState && (\n <div className=\"pt-3 space-y-3 animate-in fade-in slide-in-from-top-2 duration-200\">\n <div>\n <span className=\"text-xs text-muted-foreground mb-2 block font-medium\">\n {thumbState === \"up\" ? \"What worked well?\" : \"What needs improvement?\"}\n </span>\n <div className=\"flex flex-wrap gap-1.5\">\n {(thumbState === \"up\" ? positivePills : negativePills).map((pill) => (\n <button\n key={pill}\n onClick={() => togglePill(pill)}\n className={`px-2.5 py-1 rounded-full text-[11px] font-medium border transition-colors ${\n selectedPills.includes(pill)\n ? thumbState === \"up\"\n ? \"bg-emerald-100 text-emerald-700 border-emerald-200 dark:bg-emerald-900/30 dark:text-emerald-300 dark:border-emerald-800\"\n : \"bg-red-100 text-red-700 border-red-200 dark:bg-red-900/30 dark:text-red-300 dark:border-red-800\"\n : \"bg-background text-muted-foreground border-border hover:bg-muted/50 hover:text-foreground\"\n }`}\n >\n {pill}\n </button>\n ))}\n </div>\n </div>\n\n <textarea\n value={detailText}\n onChange={(e) => setDetailText(e.target.value)}\n placeholder={thumbState === \"up\" ? \"Add specific praise (optional)...\" : \"Provide specific instructions (optional)...\"}\n className=\"w-full text-xs bg-background border border-border rounded-md px-2.5 py-2 text-foreground placeholder:text-muted-foreground/50 focus:outline-none focus:ring-1 focus:ring-indigo-500/50 focus:border-indigo-500/50 resize-none min-h-[60px]\"\n />\n\n <div className=\"flex items-center gap-2 pt-1\">\n {thumbState === \"down\" ? (\n <>\n <button\n onClick={handleRegenerate}\n disabled={selectedPills.length === 0 && detailText.length === 0}\n className={`flex-1 py-1.5 rounded-md text-xs font-semibold transition-colors flex items-center justify-center gap-1.5 ${\n selectedPills.length > 0 || detailText.length > 0\n ? \"bg-foreground text-background hover:bg-foreground/90\"\n : \"bg-muted text-muted-foreground cursor-not-allowed\"\n }`}\n >\n <RefreshCw className=\"w-3 h-3\" />\n Regenerate draft\n </button>\n <button\n onClick={handleDiscard}\n className=\"flex-1 py-1.5 rounded-md text-xs font-medium transition-colors border bg-background text-foreground border-border hover:bg-muted/50 flex items-center justify-center gap-1.5\"\n >\n Discard draft\n </button>\n </>\n ) : (\n <button\n onClick={handleSubmit}\n className=\"flex-1 py-1.5 rounded-md text-xs font-semibold transition-colors bg-foreground text-background hover:bg-foreground/90 border-transparent\"\n >\n Submit feedback\n </button>\n )}\n </div>\n </div>\n )}\n </div>\n )\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/draft-feedback-inline.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport {\n ThumbsUp,\n ThumbsDown,\n Check,\n RefreshCw,\n} from \"lucide-react\"\n\n// ---------------------------------------------------------------------------\n// DraftFeedbackInline\n// ---------------------------------------------------------------------------\n\nconst positivePills = [\"Tone\", \"Personalization\", \"Length\", \"CTA\", \"Other\"]\nconst negativePills = [\"Too formal\", \"Too casual\", \"Too long\", \"Missing context\", \"Wrong angle\", \"Factual error\", \"Other\"]\n\nexport interface DraftFeedbackInlineProps {\n initialDirection?: 'up' | 'down' | null\n onRegenerateRequest?: (pills: string[], detail: string) => void\n onSubmitFeedback?: (type: \"up\" | \"down\", pills: string[], detail: string) => void\n onDiscardRequest?: (pills: string[], detail: string) => void\n}\n\nexport function DraftFeedbackInline({\n initialDirection,\n onRegenerateRequest,\n onSubmitFeedback,\n onDiscardRequest,\n}: DraftFeedbackInlineProps) {\n const [thumbState, setThumbState] = React.useState<\"up\" | \"down\" | null>(initialDirection ?? null)\n const [selectedPills, setSelectedPills] = React.useState<string[]>([])\n const [detailText, setDetailText] = React.useState(\"\")\n const [noted, setNoted] = React.useState(false)\n const [regenerated, setRegenerated] = React.useState(false)\n\n const togglePill = React.useCallback((pill: string) => {\n setSelectedPills((prev) => (prev.includes(pill) ? prev.filter((p) => p !== pill) : [...prev, pill]))\n }, [])\n\n const handleSubmit = React.useCallback(() => {\n if (!thumbState) return\n onSubmitFeedback?.(thumbState, selectedPills, detailText)\n setNoted(true)\n setTimeout(() => {\n setThumbState(null)\n setSelectedPills([])\n setDetailText(\"\")\n setNoted(false)\n }, 3000)\n }, [thumbState, selectedPills, detailText, onSubmitFeedback])\n\n const handleRegenerate = React.useCallback(() => {\n if (!thumbState) return\n onRegenerateRequest?.(selectedPills, detailText)\n setRegenerated(true)\n setTimeout(() => {\n setThumbState(null)\n setSelectedPills([])\n setDetailText(\"\")\n setRegenerated(false)\n }, 3000)\n }, [thumbState, selectedPills, detailText, onRegenerateRequest])\n\n const handleDiscard = React.useCallback(() => {\n if (!thumbState) return\n onDiscardRequest?.(selectedPills, detailText)\n }, [thumbState, selectedPills, detailText, onDiscardRequest])\n\n if (noted) {\n return (\n <div className=\"flex items-center gap-1.5 py-1 animate-in fade-in slide-in-from-top-1 duration-200\">\n <Check className=\"w-3.5 h-3.5 text-foreground\" />\n <span className=\"text-xs text-muted-foreground\">Feedback recorded</span>\n </div>\n )\n }\n\n if (regenerated) {\n return (\n <div className=\"py-2 animate-in fade-in slide-in-from-top-1 duration-200\">\n <div className=\"flex items-center gap-2 px-3 py-2 rounded-md bg-indigo-50 dark:bg-indigo-950/30 border border-indigo-200 dark:border-indigo-800\">\n <RefreshCw className=\"w-3 h-3 text-indigo-500 animate-spin\" />\n <span className=\"text-xs font-medium text-indigo-600 dark:text-indigo-400\">Regenerating draft...</span>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-foreground font-medium\">How&apos;s this draft?</span>\n <div className=\"flex gap-1\">\n <button\n onClick={() => {\n setThumbState(thumbState === \"up\" ? null : \"up\")\n setSelectedPills([])\n setDetailText(\"\")\n }}\n className={`p-1.5 rounded transition-colors ${\n thumbState === \"up\"\n ? \"bg-muted text-foreground\"\n : \"hover:bg-muted text-muted-foreground hover:text-foreground\"\n }`}\n >\n <ThumbsUp className=\"w-4 h-4\" />\n </button>\n <button\n onClick={() => {\n setThumbState(thumbState === \"down\" ? null : \"down\")\n setSelectedPills([])\n setDetailText(\"\")\n }}\n className={`p-1.5 rounded transition-colors ${\n thumbState === \"down\"\n ? \"bg-red-50 text-red-600 dark:bg-red-950/30 dark:text-red-400\"\n : \"hover:bg-muted text-muted-foreground hover:text-foreground\"\n }`}\n >\n <ThumbsDown className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n\n {thumbState && (\n <div className=\"pt-2 space-y-2.5 animate-in fade-in slide-in-from-top-2 duration-200\">\n <div>\n <span className=\"text-xs text-muted-foreground mb-2 block font-medium\">\n {thumbState === \"up\" ? \"What worked well?\" : \"What needs improvement?\"}\n </span>\n <div className=\"flex flex-wrap gap-2\">\n {(thumbState === \"up\" ? positivePills : negativePills).map((pill) => (\n <button\n key={pill}\n onClick={() => togglePill(pill)}\n className={`px-3 py-1.5 rounded-full text-[11px] font-medium border transition-colors ${\n selectedPills.includes(pill)\n ? thumbState === \"up\"\n ? \"bg-muted text-foreground border-border\"\n : \"bg-red-50 text-red-700 border-red-200 dark:bg-red-950/30 dark:text-red-300 dark:border-red-800\"\n : \"bg-background text-muted-foreground border-border hover:bg-muted/50 hover:text-foreground\"\n }`}\n >\n {pill}\n </button>\n ))}\n </div>\n </div>\n\n <textarea\n value={detailText}\n onChange={(e) => setDetailText(e.target.value)}\n placeholder={thumbState === \"up\" ? \"Add specific praise (optional)...\" : \"Provide specific instructions (optional)...\"}\n className=\"w-full text-xs bg-background border border-border rounded-md px-2.5 py-2 text-foreground placeholder:text-muted-foreground/50 focus:outline-none focus:ring-1 focus:ring-indigo-500/50 focus:border-indigo-500/50 resize-none min-h-[60px]\"\n />\n\n <div className=\"flex items-center gap-2.5 pt-2\">\n {thumbState === \"down\" ? (\n <>\n <button\n onClick={handleRegenerate}\n disabled={selectedPills.length === 0 && detailText.length === 0}\n className={`flex-1 py-1.5 rounded-md text-xs font-semibold transition-colors flex items-center justify-center gap-1.5 ${\n selectedPills.length > 0 || detailText.length > 0\n ? \"bg-foreground text-background hover:bg-foreground/90\"\n : \"bg-muted text-muted-foreground cursor-not-allowed\"\n }`}\n >\n <RefreshCw className=\"w-3 h-3\" />\n Regenerate draft\n </button>\n <button\n onClick={handleDiscard}\n className=\"flex-1 py-1.5 rounded-md text-xs font-medium transition-colors border bg-background text-foreground border-border hover:bg-muted/50 flex items-center justify-center gap-1.5\"\n >\n Discard draft\n </button>\n </>\n ) : (\n <button\n onClick={handleSubmit}\n className=\"flex-1 py-1.5 rounded-md text-xs font-semibold transition-colors bg-foreground text-background hover:bg-foreground/90 border-transparent\"\n >\n Submit feedback\n </button>\n )}\n </div>\n </div>\n )}\n </div>\n )\n}\n\n"],"mappings":"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","names":[]}
@@ -116,9 +116,9 @@ function Trigger({ className }) {
116
116
  onClick: () => handleThumbClick("up"),
117
117
  className: cn(
118
118
  "p-1.5 rounded transition-colors",
119
- thumbState === "up" ? "bg-emerald-100 text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400" : "hover:bg-muted text-muted-foreground hover:text-foreground"
119
+ thumbState === "up" ? "bg-muted text-foreground" : "hover:bg-muted text-muted-foreground hover:text-foreground"
120
120
  ),
121
- children: /* @__PURE__ */ jsx(ThumbsUp, { className: "w-3.5 h-3.5", fill: thumbState === "up" ? "currentColor" : "none" })
121
+ children: /* @__PURE__ */ jsx(ThumbsUp, { className: "w-3.5 h-3.5" })
122
122
  }
123
123
  ),
124
124
  /* @__PURE__ */ jsx(
@@ -128,9 +128,9 @@ function Trigger({ className }) {
128
128
  onClick: () => handleThumbClick("down"),
129
129
  className: cn(
130
130
  "p-1.5 rounded transition-colors",
131
- thumbState === "down" ? "bg-red-100 text-red-600 dark:bg-red-900/30 dark:text-red-400" : "hover:bg-muted text-muted-foreground hover:text-foreground"
131
+ thumbState === "down" ? "bg-red-50 text-red-600 dark:bg-red-950/30 dark:text-red-400" : "hover:bg-muted text-muted-foreground hover:text-foreground"
132
132
  ),
133
- children: /* @__PURE__ */ jsx(ThumbsDown, { className: "w-3.5 h-3.5", fill: thumbState === "down" ? "currentColor" : "none" })
133
+ children: /* @__PURE__ */ jsx(ThumbsDown, { className: "w-3.5 h-3.5" })
134
134
  }
135
135
  )
136
136
  ] });
@@ -158,7 +158,7 @@ function Panel({ className }) {
158
158
  onClick: () => togglePill(pill),
159
159
  className: cn(
160
160
  "px-2.5 py-1 rounded-full text-[11px] font-medium border transition-colors",
161
- selectedPills.includes(pill) ? thumbState === "up" ? "bg-emerald-100 text-emerald-700 border-emerald-200 dark:bg-emerald-900/30 dark:text-emerald-300 dark:border-emerald-800" : "bg-red-100 text-red-700 border-red-200 dark:bg-red-900/30 dark:text-red-300 dark:border-red-800" : "bg-background text-muted-foreground border-border hover:bg-muted/50 hover:text-foreground"
161
+ selectedPills.includes(pill) ? thumbState === "up" ? "bg-muted text-foreground border-border" : "bg-red-50 text-red-700 border-red-200 dark:bg-red-950/30 dark:text-red-300 dark:border-red-800" : "bg-background text-muted-foreground border-border hover:bg-muted/50 hover:text-foreground"
162
162
  ),
163
163
  children: pill
164
164
  },
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/score-feedback.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { ThumbsUp, ThumbsDown, Check } from \"lucide-react\"\nimport { cn } from \"../lib/utils\"\n\nconst positivePills = [\n \"Right timing\",\n \"Accurate data\",\n \"Good prospect fit\",\n \"Actionable\",\n]\n\nconst negativePills = [\n \"Bad timing\",\n \"Inaccurate data\",\n \"Wrong prospect\",\n \"Already handled\",\n \"Not actionable\",\n \"Other\",\n]\n\ninterface SubmittedScoreFeedback {\n type: \"up\" | \"down\"\n pills: string[]\n detail: string\n}\n\ninterface ScoreFeedbackState {\n thumbState: \"up\" | \"down\" | null\n selectedPills: string[]\n detailText: string\n notedType: \"up\" | \"down\" | null\n submittedFeedback: SubmittedScoreFeedback | null\n otherSelected: boolean\n hasRequiredInput: boolean\n handleThumbClick: (type: \"up\" | \"down\") => void\n togglePill: (pill: string) => void\n setDetailText: (text: string) => void\n handleSubmit: () => void\n editSubmitted: () => void\n}\n\nconst ScoreFeedbackCtx = React.createContext<ScoreFeedbackState | null>(null)\n\nfunction useScoreFeedback() {\n const ctx = React.useContext(ScoreFeedbackCtx)\n if (!ctx) throw new Error(\"Must be used within ScoreFeedback.Root\")\n return ctx\n}\n\ninterface RootProps {\n children: React.ReactNode\n onSubmitFeedback?: (type: \"up\" | \"down\", pills: string[], detail: string) => void\n initialFeedback?: { type: \"up\" | \"down\"; pills: string[]; detail: string } | null\n}\n\nfunction Root({ children, onSubmitFeedback, initialFeedback }: RootProps) {\n const [thumbState, setThumbState] = React.useState<\"up\" | \"down\" | null>(null)\n const [selectedPills, setSelectedPills] = React.useState<string[]>([])\n const [detailText, setDetailTextState] = React.useState(\"\")\n const [notedType, setNotedType] = React.useState<\"up\" | \"down\" | null>(null)\n const [submittedFeedback, setSubmittedFeedback] = React.useState<SubmittedScoreFeedback | null>(\n initialFeedback ?? null\n )\n\n // Sync submitted feedback when initialFeedback prop changes (e.g. async\n // detail load). Skip when the user has an in-progress edit (thumbState set).\n React.useEffect(() => {\n if (thumbState !== null) return\n setSubmittedFeedback(initialFeedback ?? null)\n }, [initialFeedback]) // eslint-disable-line react-hooks/exhaustive-deps -- intentionally omits thumbState to read it as a guard, not a trigger\n\n const otherSelected = selectedPills.includes(\"Other\")\n\n const hasRequiredInput =\n thumbState === \"down\"\n ? selectedPills.length > 0 && (!otherSelected || detailText.trim().length > 0)\n : selectedPills.length > 0 || detailText.trim().length > 0\n\n const togglePill = React.useCallback((pill: string) => {\n setSelectedPills((prev) =>\n prev.includes(pill) ? prev.filter((p) => p !== pill) : [...prev, pill]\n )\n }, [])\n\n const handleThumbClick = React.useCallback((type: \"up\" | \"down\") => {\n setThumbState((prev) => (prev === type ? null : type))\n setSelectedPills([])\n setDetailTextState(\"\")\n }, [])\n\n const handleSubmit = React.useCallback(() => {\n if (!thumbState) return\n onSubmitFeedback?.(thumbState, selectedPills, detailText)\n setSubmittedFeedback({ type: thumbState, pills: [...selectedPills], detail: detailText.trim() })\n setNotedType(thumbState)\n setThumbState(null)\n setSelectedPills([])\n setDetailTextState(\"\")\n setTimeout(() => setNotedType(null), 3000)\n }, [thumbState, selectedPills, detailText, onSubmitFeedback])\n\n const editSubmitted = React.useCallback(() => {\n if (!submittedFeedback) return\n setThumbState(submittedFeedback.type)\n setSelectedPills([...submittedFeedback.pills])\n setDetailTextState(submittedFeedback.detail)\n setNotedType(null)\n }, [submittedFeedback])\n\n return (\n <ScoreFeedbackCtx.Provider\n value={{\n thumbState,\n selectedPills,\n detailText,\n notedType,\n submittedFeedback,\n otherSelected,\n hasRequiredInput,\n handleThumbClick,\n togglePill,\n setDetailText: setDetailTextState,\n handleSubmit,\n editSubmitted,\n }}\n >\n {children}\n </ScoreFeedbackCtx.Provider>\n )\n}\n\nfunction Trigger({ className }: { className?: string }) {\n const { thumbState, notedType, submittedFeedback, handleThumbClick, editSubmitted } = useScoreFeedback()\n\n if (notedType || (submittedFeedback && !thumbState)) {\n const label = notedType\n ? notedType === \"up\" ? \"Noted\" : \"Recorded\"\n : submittedFeedback?.type === \"up\" ? \"Noted\" : \"Recorded\"\n\n return (\n <button\n type=\"button\"\n onClick={submittedFeedback ? editSubmitted : undefined}\n className={cn(\n \"flex items-center gap-1 shrink-0 rounded px-1.5 py-1 transition-colors\",\n submittedFeedback ? \"cursor-pointer hover:bg-muted/50\" : \"cursor-default\",\n className,\n )}\n >\n <Check className=\"w-3 h-3 text-emerald-500\" />\n <span className=\"text-[11px] text-muted-foreground\">{label}</span>\n </button>\n )\n }\n\n return (\n <div className={cn(\"flex gap-0.5 shrink-0\", className)}>\n <button\n type=\"button\"\n onClick={() => handleThumbClick(\"up\")}\n className={cn(\n \"p-1.5 rounded transition-colors\",\n thumbState === \"up\"\n ? \"bg-emerald-100 text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400\"\n : \"hover:bg-muted text-muted-foreground hover:text-foreground\"\n )}\n >\n <ThumbsUp className=\"w-3.5 h-3.5\" fill={thumbState === \"up\" ? \"currentColor\" : \"none\"} />\n </button>\n <button\n type=\"button\"\n onClick={() => handleThumbClick(\"down\")}\n className={cn(\n \"p-1.5 rounded transition-colors\",\n thumbState === \"down\"\n ? \"bg-red-100 text-red-600 dark:bg-red-900/30 dark:text-red-400\"\n : \"hover:bg-muted text-muted-foreground hover:text-foreground\"\n )}\n >\n <ThumbsDown className=\"w-3.5 h-3.5\" fill={thumbState === \"down\" ? \"currentColor\" : \"none\"} />\n </button>\n </div>\n )\n}\n\nfunction Panel({ className }: { className?: string }) {\n const {\n thumbState,\n selectedPills,\n detailText,\n otherSelected,\n hasRequiredInput,\n togglePill,\n setDetailText,\n handleSubmit,\n } = useScoreFeedback()\n\n if (!thumbState) return null\n\n return (\n <div className={cn(\"overflow-hidden\", className)}>\n <div className=\"mt-4 pt-4 pb-1 space-y-3 border-t border-border/60\">\n <span className=\"text-[11px] font-bold text-muted-foreground/70 uppercase tracking-wider\">\n How&apos;s this score?\n </span>\n <div>\n <span className=\"text-xs text-muted-foreground mb-2 block font-medium\">\n {thumbState === \"up\" ? \"What was useful?\" : \"What\\u2019s the issue?\"}\n </span>\n <div className=\"flex flex-wrap gap-1.5\">\n {(thumbState === \"up\" ? positivePills : negativePills).map((pill) => (\n <button\n key={pill}\n type=\"button\"\n onClick={() => togglePill(pill)}\n className={cn(\n \"px-2.5 py-1 rounded-full text-[11px] font-medium border transition-colors\",\n selectedPills.includes(pill)\n ? thumbState === \"up\"\n ? \"bg-emerald-100 text-emerald-700 border-emerald-200 dark:bg-emerald-900/30 dark:text-emerald-300 dark:border-emerald-800\"\n : \"bg-red-100 text-red-700 border-red-200 dark:bg-red-900/30 dark:text-red-300 dark:border-red-800\"\n : \"bg-background text-muted-foreground border-border hover:bg-muted/50 hover:text-foreground\"\n )}\n >\n {pill}\n </button>\n ))}\n </div>\n </div>\n\n <div className=\"space-y-1\">\n <input\n type=\"text\"\n value={detailText}\n onChange={(e) => setDetailText(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && hasRequiredInput) handleSubmit()\n }}\n placeholder={\n thumbState === \"up\"\n ? \"Tell us more (optional)\"\n : \"e.g., The risk factors are outdated\"\n }\n className=\"w-full text-xs bg-background border border-border rounded-md px-2.5 py-2 text-foreground placeholder:text-muted-foreground/50 focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n {otherSelected && detailText.trim().length === 0 && (\n <span className=\"text-[10px] text-red-500\">\n Please describe when &ldquo;Other&rdquo; is selected\n </span>\n )}\n </div>\n\n <div className=\"flex items-center gap-2 pt-1\">\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={!hasRequiredInput}\n className={cn(\n \"flex-1 py-1.5 rounded-md text-xs font-semibold transition-colors\",\n hasRequiredInput\n ? \"bg-foreground text-background hover:bg-foreground/90\"\n : \"bg-muted text-muted-foreground cursor-not-allowed\"\n )}\n >\n Submit\n </button>\n </div>\n </div>\n </div>\n )\n}\n\nexport const ScoreFeedback = { Root, Trigger, Panel }\nexport { useScoreFeedback }\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/score-feedback.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { ThumbsUp, ThumbsDown, Check } from \"lucide-react\"\nimport { cn } from \"../lib/utils\"\n\nconst positivePills = [\n \"Right timing\",\n \"Accurate data\",\n \"Good prospect fit\",\n \"Actionable\",\n]\n\nconst negativePills = [\n \"Bad timing\",\n \"Inaccurate data\",\n \"Wrong prospect\",\n \"Already handled\",\n \"Not actionable\",\n \"Other\",\n]\n\ninterface SubmittedScoreFeedback {\n type: \"up\" | \"down\"\n pills: string[]\n detail: string\n}\n\ninterface ScoreFeedbackState {\n thumbState: \"up\" | \"down\" | null\n selectedPills: string[]\n detailText: string\n notedType: \"up\" | \"down\" | null\n submittedFeedback: SubmittedScoreFeedback | null\n otherSelected: boolean\n hasRequiredInput: boolean\n handleThumbClick: (type: \"up\" | \"down\") => void\n togglePill: (pill: string) => void\n setDetailText: (text: string) => void\n handleSubmit: () => void\n editSubmitted: () => void\n}\n\nconst ScoreFeedbackCtx = React.createContext<ScoreFeedbackState | null>(null)\n\nfunction useScoreFeedback() {\n const ctx = React.useContext(ScoreFeedbackCtx)\n if (!ctx) throw new Error(\"Must be used within ScoreFeedback.Root\")\n return ctx\n}\n\ninterface RootProps {\n children: React.ReactNode\n onSubmitFeedback?: (type: \"up\" | \"down\", pills: string[], detail: string) => void\n initialFeedback?: { type: \"up\" | \"down\"; pills: string[]; detail: string } | null\n}\n\nfunction Root({ children, onSubmitFeedback, initialFeedback }: RootProps) {\n const [thumbState, setThumbState] = React.useState<\"up\" | \"down\" | null>(null)\n const [selectedPills, setSelectedPills] = React.useState<string[]>([])\n const [detailText, setDetailTextState] = React.useState(\"\")\n const [notedType, setNotedType] = React.useState<\"up\" | \"down\" | null>(null)\n const [submittedFeedback, setSubmittedFeedback] = React.useState<SubmittedScoreFeedback | null>(\n initialFeedback ?? null\n )\n\n // Sync submitted feedback when initialFeedback prop changes (e.g. async\n // detail load). Skip when the user has an in-progress edit (thumbState set).\n React.useEffect(() => {\n if (thumbState !== null) return\n setSubmittedFeedback(initialFeedback ?? null)\n }, [initialFeedback]) // eslint-disable-line react-hooks/exhaustive-deps -- intentionally omits thumbState to read it as a guard, not a trigger\n\n const otherSelected = selectedPills.includes(\"Other\")\n\n const hasRequiredInput =\n thumbState === \"down\"\n ? selectedPills.length > 0 && (!otherSelected || detailText.trim().length > 0)\n : selectedPills.length > 0 || detailText.trim().length > 0\n\n const togglePill = React.useCallback((pill: string) => {\n setSelectedPills((prev) =>\n prev.includes(pill) ? prev.filter((p) => p !== pill) : [...prev, pill]\n )\n }, [])\n\n const handleThumbClick = React.useCallback((type: \"up\" | \"down\") => {\n setThumbState((prev) => (prev === type ? null : type))\n setSelectedPills([])\n setDetailTextState(\"\")\n }, [])\n\n const handleSubmit = React.useCallback(() => {\n if (!thumbState) return\n onSubmitFeedback?.(thumbState, selectedPills, detailText)\n setSubmittedFeedback({ type: thumbState, pills: [...selectedPills], detail: detailText.trim() })\n setNotedType(thumbState)\n setThumbState(null)\n setSelectedPills([])\n setDetailTextState(\"\")\n setTimeout(() => setNotedType(null), 3000)\n }, [thumbState, selectedPills, detailText, onSubmitFeedback])\n\n const editSubmitted = React.useCallback(() => {\n if (!submittedFeedback) return\n setThumbState(submittedFeedback.type)\n setSelectedPills([...submittedFeedback.pills])\n setDetailTextState(submittedFeedback.detail)\n setNotedType(null)\n }, [submittedFeedback])\n\n return (\n <ScoreFeedbackCtx.Provider\n value={{\n thumbState,\n selectedPills,\n detailText,\n notedType,\n submittedFeedback,\n otherSelected,\n hasRequiredInput,\n handleThumbClick,\n togglePill,\n setDetailText: setDetailTextState,\n handleSubmit,\n editSubmitted,\n }}\n >\n {children}\n </ScoreFeedbackCtx.Provider>\n )\n}\n\nfunction Trigger({ className }: { className?: string }) {\n const { thumbState, notedType, submittedFeedback, handleThumbClick, editSubmitted } = useScoreFeedback()\n\n if (notedType || (submittedFeedback && !thumbState)) {\n const label = notedType\n ? notedType === \"up\" ? \"Noted\" : \"Recorded\"\n : submittedFeedback?.type === \"up\" ? \"Noted\" : \"Recorded\"\n\n return (\n <button\n type=\"button\"\n onClick={submittedFeedback ? editSubmitted : undefined}\n className={cn(\n \"flex items-center gap-1 shrink-0 rounded px-1.5 py-1 transition-colors\",\n submittedFeedback ? \"cursor-pointer hover:bg-muted/50\" : \"cursor-default\",\n className,\n )}\n >\n <Check className=\"w-3 h-3 text-emerald-500\" />\n <span className=\"text-[11px] text-muted-foreground\">{label}</span>\n </button>\n )\n }\n\n return (\n <div className={cn(\"flex gap-0.5 shrink-0\", className)}>\n <button\n type=\"button\"\n onClick={() => handleThumbClick(\"up\")}\n className={cn(\n \"p-1.5 rounded transition-colors\",\n thumbState === \"up\"\n ? \"bg-muted text-foreground\"\n : \"hover:bg-muted text-muted-foreground hover:text-foreground\"\n )}\n >\n <ThumbsUp className=\"w-3.5 h-3.5\" />\n </button>\n <button\n type=\"button\"\n onClick={() => handleThumbClick(\"down\")}\n className={cn(\n \"p-1.5 rounded transition-colors\",\n thumbState === \"down\"\n ? \"bg-red-50 text-red-600 dark:bg-red-950/30 dark:text-red-400\"\n : \"hover:bg-muted text-muted-foreground hover:text-foreground\"\n )}\n >\n <ThumbsDown className=\"w-3.5 h-3.5\" />\n </button>\n </div>\n )\n}\n\nfunction Panel({ className }: { className?: string }) {\n const {\n thumbState,\n selectedPills,\n detailText,\n otherSelected,\n hasRequiredInput,\n togglePill,\n setDetailText,\n handleSubmit,\n } = useScoreFeedback()\n\n if (!thumbState) return null\n\n return (\n <div className={cn(\"overflow-hidden\", className)}>\n <div className=\"mt-4 pt-4 pb-1 space-y-3 border-t border-border/60\">\n <span className=\"text-[11px] font-bold text-muted-foreground/70 uppercase tracking-wider\">\n How&apos;s this score?\n </span>\n <div>\n <span className=\"text-xs text-muted-foreground mb-2 block font-medium\">\n {thumbState === \"up\" ? \"What was useful?\" : \"What\\u2019s the issue?\"}\n </span>\n <div className=\"flex flex-wrap gap-1.5\">\n {(thumbState === \"up\" ? positivePills : negativePills).map((pill) => (\n <button\n key={pill}\n type=\"button\"\n onClick={() => togglePill(pill)}\n className={cn(\n \"px-2.5 py-1 rounded-full text-[11px] font-medium border transition-colors\",\n selectedPills.includes(pill)\n ? thumbState === \"up\"\n ? \"bg-muted text-foreground border-border\"\n : \"bg-red-50 text-red-700 border-red-200 dark:bg-red-950/30 dark:text-red-300 dark:border-red-800\"\n : \"bg-background text-muted-foreground border-border hover:bg-muted/50 hover:text-foreground\"\n )}\n >\n {pill}\n </button>\n ))}\n </div>\n </div>\n\n <div className=\"space-y-1\">\n <input\n type=\"text\"\n value={detailText}\n onChange={(e) => setDetailText(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && hasRequiredInput) handleSubmit()\n }}\n placeholder={\n thumbState === \"up\"\n ? \"Tell us more (optional)\"\n : \"e.g., The risk factors are outdated\"\n }\n className=\"w-full text-xs bg-background border border-border rounded-md px-2.5 py-2 text-foreground placeholder:text-muted-foreground/50 focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n {otherSelected && detailText.trim().length === 0 && (\n <span className=\"text-[10px] text-red-500\">\n Please describe when &ldquo;Other&rdquo; is selected\n </span>\n )}\n </div>\n\n <div className=\"flex items-center gap-2 pt-1\">\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={!hasRequiredInput}\n className={cn(\n \"flex-1 py-1.5 rounded-md text-xs font-semibold transition-colors\",\n hasRequiredInput\n ? \"bg-foreground text-background hover:bg-foreground/90\"\n : \"bg-muted text-muted-foreground cursor-not-allowed\"\n )}\n >\n Submit\n </button>\n </div>\n </div>\n </div>\n )\n}\n\nexport const ScoreFeedback = { Root, Trigger, Panel }\nexport { useScoreFeedback }\n"],"mappings":"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","names":[]}
@@ -652,6 +652,7 @@ function SuggestedActionCard({
652
652
  );
653
653
  const [showAiEdit, setShowAiEdit] = React.useState(false);
654
654
  const [feedbackOpen, setFeedbackOpen] = React.useState(false);
655
+ const [feedbackDirection, setFeedbackDirection] = React.useState(null);
655
656
  const [followUpEnabled, setFollowUpEnabled] = React.useState((_f = (_e = action.followUp) == null ? void 0 : _e.enabled) != null ? _f : false);
656
657
  const [threadExpanded, setThreadExpanded] = React.useState(false);
657
658
  const [expandedMessageId, setExpandedMessageId] = React.useState(null);
@@ -726,16 +727,32 @@ function SuggestedActionCard({
726
727
  /* @__PURE__ */ jsx(
727
728
  "button",
728
729
  {
729
- onClick: () => setFeedbackOpen(!feedbackOpen),
730
- className: `p-1.5 rounded transition-colors ${feedbackOpen ? "bg-emerald-100 text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400" : "hover:bg-muted text-muted-foreground hover:text-foreground"}`,
730
+ onClick: () => {
731
+ if (feedbackOpen && feedbackDirection === "up") {
732
+ setFeedbackOpen(false);
733
+ setFeedbackDirection(null);
734
+ } else {
735
+ setFeedbackDirection("up");
736
+ setFeedbackOpen(true);
737
+ }
738
+ },
739
+ className: `p-1.5 rounded transition-colors ${feedbackOpen && feedbackDirection === "up" ? "bg-muted text-foreground" : "hover:bg-muted text-muted-foreground hover:text-foreground"}`,
731
740
  children: /* @__PURE__ */ jsx(ThumbsUp, { className: "w-3.5 h-3.5" })
732
741
  }
733
742
  ),
734
743
  /* @__PURE__ */ jsx(
735
744
  "button",
736
745
  {
737
- onClick: () => setFeedbackOpen(!feedbackOpen),
738
- className: "p-1.5 rounded transition-colors hover:bg-muted text-muted-foreground hover:text-foreground",
746
+ onClick: () => {
747
+ if (feedbackOpen && feedbackDirection === "down") {
748
+ setFeedbackOpen(false);
749
+ setFeedbackDirection(null);
750
+ } else {
751
+ setFeedbackDirection("down");
752
+ setFeedbackOpen(true);
753
+ }
754
+ },
755
+ className: `p-1.5 rounded transition-colors ${feedbackOpen && feedbackDirection === "down" ? "bg-red-50 text-red-600 dark:bg-red-950/30 dark:text-red-400" : "hover:bg-muted text-muted-foreground hover:text-foreground"}`,
739
756
  children: /* @__PURE__ */ jsx(ThumbsDown, { className: "w-3.5 h-3.5" })
740
757
  }
741
758
  ),
@@ -755,6 +772,7 @@ function SuggestedActionCard({
755
772
  feedbackOpen && /* @__PURE__ */ jsx("div", { className: "px-5 py-3 border-b border-border/40 animate-in fade-in slide-in-from-top-2 duration-200", children: /* @__PURE__ */ jsx(
756
773
  DraftFeedbackInline,
757
774
  {
775
+ initialDirection: feedbackDirection,
758
776
  onRegenerateRequest: (pills, detail) => {
759
777
  onFeedback == null ? void 0 : onFeedback("down", pills, detail);
760
778
  },
@@ -765,7 +783,8 @@ function SuggestedActionCard({
765
783
  onFeedback == null ? void 0 : onFeedback("down", pills, detail);
766
784
  onDismiss == null ? void 0 : onDismiss(action.id);
767
785
  }
768
- }
786
+ },
787
+ `feedback-${feedbackDirection}`
769
788
  ) }),
770
789
  isThreadReply && action.replyTo && /* @__PURE__ */ jsxs("div", { className: "border-b border-border/40", children: [
771
790
  action.threadMessages && action.threadMessages.length > 1 && /* @__PURE__ */ jsx("div", { className: "px-5 py-2 border-b border-border/40", children: /* @__PURE__ */ jsxs(