From 8bfbf375a120e471f41963b428eece088c03b1a0 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 26 Jun 2026 21:29:18 +0000 Subject: [PATCH] feat: add disabled state to chat input when offline Co-authored-by: teerthsharma <78080953+teerthsharma@users.noreply.github.com> --- .jules/palette.md | 5 ++++- .../APEIRON/frontend/components/ChatInterface.tsx | 13 +++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.jules/palette.md b/.jules/palette.md index 498b2ba..9cb4d2e 100644 --- a/.jules/palette.md +++ b/.jules/palette.md @@ -1,3 +1,6 @@ ## 2024-06-01 - Dynamic Tooltips for Disabled States **Learning:** Found that static tooltips like "Send message" on disabled submit buttons can be confusing, particularly when users don't know *why* the button is disabled. In React/Next.js, toggling the `title` attribute dynamically based on the same condition that disables the button (`!input.trim() ? "Enter a message to send" : "Send message"`) provides immediate contextual feedback for screen reader and mouse users alike. -**Action:** When creating form submit buttons, always tie the `title` or `aria-label` attribute dynamically to the validation state, and ensure visual disabled styling (`disabled:cursor-not-allowed`) is coupled with `focus-visible` styles for comprehensive accessibility. \ No newline at end of file +**Action:** When creating form submit buttons, always tie the `title` or `aria-label` attribute dynamically to the validation state, and ensure visual disabled styling (`disabled:cursor-not-allowed`) is coupled with `focus-visible` styles for comprehensive accessibility. +## 2026-06-26 - Network-State Driven UI Feedback +**Learning:** When core interactive elements (like chat inputs) depend on a network or tunnel state (e.g., `tunnelStatus`), simply disabling the element can leave users confused if the placeholder text still implies they can interact with it (e.g. "Inject knowledge..."). Dynamically updating both the placeholder to indicate the offline state (e.g. "Neuro-Link Offline...") and the disabled `aria-label`/`title` provides necessary context. +**Action:** Always link contextual UI properties (placeholders, tooltips, aria-labels) to the same underlying connection/network state that drives the disabled state. diff --git a/future/apeiron-runtime/APEIRON/frontend/components/ChatInterface.tsx b/future/apeiron-runtime/APEIRON/frontend/components/ChatInterface.tsx index ca05d58..94f060d 100644 --- a/future/apeiron-runtime/APEIRON/frontend/components/ChatInterface.tsx +++ b/future/apeiron-runtime/APEIRON/frontend/components/ChatInterface.tsx @@ -41,7 +41,7 @@ const ThoughtItem = memo(function ThoughtItem({ thought }: { thought: string }) )}); export default function ChatInterface() { - const { messages, sendMessage, isLearning, pulseType, thoughts } = useApeiron(); + const { messages, sendMessage, isLearning, pulseType, thoughts, tunnelStatus } = useApeiron(); const [input, setInput] = useState(''); const scrollRef = useRef(null); @@ -135,15 +135,16 @@ export default function ChatInterface() { setInput(e.target.value)} - placeholder="Inject knowledge into the kernel..." + placeholder={tunnelStatus === 'LOCKED' ? "Inject knowledge into the kernel..." : "Neuro-Link Offline..."} aria-label="Message input" - className="flex-1 bg-gray-900 border border-gray-700 rounded-lg px-4 py-3 focus:outline-none focus:border-green-500 transition-colors text-white" + disabled={tunnelStatus !== 'LOCKED'} + className="flex-1 bg-gray-900 border border-gray-700 rounded-lg px-4 py-3 focus:outline-none focus:border-green-500 transition-colors text-white disabled:opacity-50 disabled:cursor-not-allowed" />