Check e.nativeEvent.isComposing and keyCode 229 in addition to
React state, fixing a race condition where compositionend fires
before keydown on some browsers (Chrome/macOS).
Fixes#20
* fix: prevent message send when Chinese IME is composing
- Add e.isComposing check to Enter key handler in ChatInput
- This prevents accidental message sending when pressing Enter to confirm Chinese/Japanese input
- Fixes issue where messages would be sent prematurely when using IME composition
Refs: #issue
* fix: prevent message send when Chinese IME is composing
- Add isComposing state to track IME composition status
- Add onCompositionStart/onCompositionEnd event handlers to textarea
- Check isComposing state in Enter key handler to prevent accidental send
This fixes the issue where pressing Enter to confirm Chinese/Japanese input
would prematurely send the message instead of just confirming the IME selection.
The fix uses explicit composition state tracking instead of relying solely on
e.isComposing, which provides more reliable cross-browser behavior.
---------
Co-authored-by: 代码专家 <coder@openclaw.ai>
When selecting a slash command without arguments (e.g. /new, /status, /help)
from the autocomplete menu, the command now executes immediately instead of
getting stuck in a loop where the menu kept intercepting Enter keypresses.
Fixes#17
Replace standalone lazy import of ReactMarkdown + remark-gfm in
ChatInput with the existing LazyMarkdown component, which already
handles lazy loading with remark-gfm, remark-breaks, and
rehype-highlight. Reduces code duplication and ensures consistent
markdown rendering between chat messages and the input preview.
Introduces a `/new` slash command that lets users create a fresh chat
session for the current agent without leaving the chat input.
- Add `createNewSession` to `useGateway` that calls `sessions.create`
on the gateway (with a client-side fallback key when the RPC is
unavailable).
- Register `/new` in the slash-command menu with i18n descriptions
across all 8 supported languages.
- Wire `onNewSession` through `Chat` → `ChatInput` so typing `/new`
triggers session creation.
- Add `extractAgentIdFromKey` and `formatAgentId` helpers to
`sessionName.ts` to derive a human-readable agent name from the
session key (e.g. `agent:my-cool-bot:…` → "My Cool Bot").
- Use the new helpers in `Header` and `App` to show per-session agent
names, especially for sub-agent sessions where the gateway-level
identity differs from the session agent.
Made-with: Cursor
- ChatInput: add aria-labels to remove file, send shortcut toggle, and stop buttons
- CodeBlock: add aria-labels to word wrap, line numbers, and collapse/expand buttons
- Header: add aria-labels to session info, copy, close, and compact buttons
Type '/' to see available OpenClaw commands (/status, /reasoning,
/verbose, /model, /compact, /reset, /help) with descriptions.
Navigate with arrow keys, select with Tab/Enter.
Supports EN/FR i18n.
Add toggle in chat input to switch between Enter-to-send (default)
and Ctrl+Enter-to-send modes. Preference persists in localStorage.
Keyboard shortcuts modal reflects the current setting.
- Hide sidebar, header, chat input, and scroll button when printing
- Reset backgrounds to white, text to black for readability
- Code blocks get light background with borders
- Tool calls styled for print (compact, bordered)
- External links show their URL in parentheses
- Chat scroll area becomes fully visible (no overflow)
- Messages avoid page-break-inside for clean pagination
- Remove shadows and backdrop filters in print
- Replace div with <main> for primary chat pane (screen reader landmark)
- Replace div with <section> for split pane
- Add skip-to-content link for keyboard navigation (Tab → jump to chat input)
- Add aria-expanded and aria-label to tool call badge buttons
- Add id='chat-input' to textarea for skip link target
- Add i18n keys for new ARIA labels (EN + FR)
- User messages appear instantly with 'sending' state (dimmed, clock icon)
- Transitions to 'sent' (checkmark) when server acknowledges
- Shows error state (alert icon, retry visible) if send fails
- Applied to both primary and secondary sessions
Suppress 3 react-hooks/set-state-in-effect warnings with targeted
eslint-disable comments. These are intentional patterns:
- ChatInput: restore draft text on session switch
- MessageSearch: reset active index on query change
- ToolCall: sync open state with global collapse/expand toggle
Lint now passes with 0 errors and 0 warnings.
Replace ~150 hardcoded Tailwind color classes (bg-zinc-*, text-zinc-*,
border-white/*, text-cyan-*, bg-cyan-*) with CSS custom properties
(--pc-*) across all 17 components.
Add @theme block in index.css for Tailwind v4 theme-aware utility
classes (bg-pc-elevated, text-pc-text, border-pc-border, etc.).
Add --pc-hover, --pc-hover-strong, --pc-separator variables per theme
(white/alpha for dark/OLED, black/alpha for light).
Theme switcher (dark/light/OLED) now actually works — all UI elements
respond to theme changes in real-time.
Fixes#55
- Add ThemeContext with CSS custom properties for all base colors
- Three theme modes: Dark (default), Light, OLED Black
- Six accent colors: Cyan, Violet, Emerald, Amber, Rose, Blue
- Theme switcher dropdown in header (palette icon)
- Persisted in localStorage
- CSS variables replace hardcoded hex colors in index.css and components
- i18n support (EN/FR) for theme labels
- Lightweight i18n system in src/lib/i18n.ts (no external deps)
- All UI strings extracted to translation keys
- English (default) and French locales included
- Set VITE_LOCALE=fr in .env for French UI
- Fallback to English for unknown locales
- Replace all French UI strings with English (Connected, Thinking, Result, Send, etc.)
- Add role="log" + aria-live="polite" to chat message area
- Add role="form" + aria-label to message input area
- Add aria-label to sidebar toggle, attach file, send, and textarea
- Add role="banner" to header, role="navigation" to sidebar
- Add role="application" to app root