Spaces:
Runtime error
Runtime error
webmuppet Claude Sonnet 4.6 commited on
Commit ·
ac3c645
1
Parent(s): c812b81
chat: bottom input matches hero — floating card, text-xl, Send label
Browse filesReplaces the compact dark footer bar with a floating rounded card
(same rgba glass style as the hero input) centred at max-w-3xl.
Textarea grows to rows=2, text-xl with transparent background.
Stop/Send buttons gain a text label to match the hero variant.
A gradient fade from #0F0027 to transparent behind the card
prevents content bleeding through.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
frontend/src/components/ChatInput.tsx
CHANGED
|
@@ -101,63 +101,69 @@ export function ChatInput({
|
|
| 101 |
);
|
| 102 |
}
|
| 103 |
|
| 104 |
-
// "bottom" variant —
|
| 105 |
return (
|
| 106 |
-
<div className="sticky bottom-0 w-full" style={{
|
| 107 |
-
<
|
| 108 |
-
|
| 109 |
-
|
| 110 |
>
|
| 111 |
-
{
|
| 112 |
-
|
| 113 |
-
<button
|
| 114 |
-
type="button"
|
| 115 |
-
onClick={onExportConversation}
|
| 116 |
-
className="shrink-0 p-2 rounded-lg text-white/70 hover:text-white hover:bg-white/10 transition-colors"
|
| 117 |
-
title="Download conversation"
|
| 118 |
-
aria-label="Download conversation"
|
| 119 |
-
>
|
| 120 |
-
<DownloadIcon />
|
| 121 |
-
</button>
|
| 122 |
-
)}
|
| 123 |
-
|
| 124 |
-
{/* Text input */}
|
| 125 |
-
<div className="flex-1">
|
| 126 |
<textarea
|
| 127 |
value={query}
|
| 128 |
onChange={(e) => setQuery(e.target.value)}
|
| 129 |
onKeyDown={handleKeyDown}
|
| 130 |
disabled={isStreaming}
|
| 131 |
placeholder={isStreaming ? "Waiting for response..." : "Ask a compliance question..."}
|
| 132 |
-
rows={
|
| 133 |
-
className="w-full resize-none
|
| 134 |
aria-label="Chat input"
|
| 135 |
/>
|
| 136 |
-
</div>
|
| 137 |
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 161 |
</div>
|
| 162 |
);
|
| 163 |
}
|
|
|
|
| 101 |
);
|
| 102 |
}
|
| 103 |
|
| 104 |
+
// "bottom" variant — floating card anchored to bottom, matching hero style
|
| 105 |
return (
|
| 106 |
+
<div className="sticky bottom-0 w-full px-4 pb-4 pt-2" style={{ background: "linear-gradient(to top, #0F0027 60%, transparent)" }}>
|
| 107 |
+
<div
|
| 108 |
+
className="mx-auto max-w-3xl rounded-2xl border border-white/10"
|
| 109 |
+
style={{ backgroundColor: "rgba(255,255,255,0.08)" }}
|
| 110 |
>
|
| 111 |
+
<form onSubmit={handleSubmit} className="flex flex-col gap-0 px-5 pt-4 pb-3">
|
| 112 |
+
{/* Large textarea — same scale as hero input */}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 113 |
<textarea
|
| 114 |
value={query}
|
| 115 |
onChange={(e) => setQuery(e.target.value)}
|
| 116 |
onKeyDown={handleKeyDown}
|
| 117 |
disabled={isStreaming}
|
| 118 |
placeholder={isStreaming ? "Waiting for response..." : "Ask a compliance question..."}
|
| 119 |
+
rows={2}
|
| 120 |
+
className="w-full resize-none border-0 bg-transparent text-xl text-white placeholder-white/40 outline-none focus:ring-0 disabled:opacity-50 disabled:cursor-not-allowed leading-relaxed"
|
| 121 |
aria-label="Chat input"
|
| 122 |
/>
|
|
|
|
| 123 |
|
| 124 |
+
{/* Action row */}
|
| 125 |
+
<div className="flex items-center justify-between pt-2">
|
| 126 |
+
{/* Download conversation button */}
|
| 127 |
+
{hasMessages && (
|
| 128 |
+
<button
|
| 129 |
+
type="button"
|
| 130 |
+
onClick={onExportConversation}
|
| 131 |
+
className="p-2 rounded-lg text-white/50 hover:text-white hover:bg-white/10 transition-colors"
|
| 132 |
+
title="Download conversation"
|
| 133 |
+
aria-label="Download conversation"
|
| 134 |
+
>
|
| 135 |
+
<DownloadIcon />
|
| 136 |
+
</button>
|
| 137 |
+
)}
|
| 138 |
+
{!hasMessages && <div />}
|
| 139 |
+
|
| 140 |
+
{/* Stop / Send */}
|
| 141 |
+
{isStreaming ? (
|
| 142 |
+
<button
|
| 143 |
+
type="button"
|
| 144 |
+
onClick={onStop}
|
| 145 |
+
className="flex items-center gap-2 px-4 py-2 rounded-xl text-sm font-medium text-white/90 hover:text-white bg-white/10 hover:bg-white/20 transition-colors"
|
| 146 |
+
title="Stop generating"
|
| 147 |
+
aria-label="Stop generating"
|
| 148 |
+
>
|
| 149 |
+
<StopIcon />
|
| 150 |
+
<span>Stop</span>
|
| 151 |
+
</button>
|
| 152 |
+
) : (
|
| 153 |
+
<button
|
| 154 |
+
type="submit"
|
| 155 |
+
disabled={!canSubmit}
|
| 156 |
+
className="flex items-center gap-2 px-4 py-2 rounded-xl text-sm font-medium text-white/90 hover:text-white bg-white/10 hover:bg-white/20 disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
|
| 157 |
+
title="Send message"
|
| 158 |
+
aria-label="Send message"
|
| 159 |
+
>
|
| 160 |
+
<SendIcon />
|
| 161 |
+
<span>Send</span>
|
| 162 |
+
</button>
|
| 163 |
+
)}
|
| 164 |
+
</div>
|
| 165 |
+
</form>
|
| 166 |
+
</div>
|
| 167 |
</div>
|
| 168 |
);
|
| 169 |
}
|