Skip to content

feat(interface): configurable Enter behavior in chat composer#600

Open
b-client-vm wants to merge 2 commits into
spacedriveapp:mainfrom
brendandebeasi:feat/599-chat-input-enter-and-resize
Open

feat(interface): configurable Enter behavior in chat composer#600
b-client-vm wants to merge 2 commits into
spacedriveapp:mainfrom
brendandebeasi:feat/599-chat-input-enter-and-resize

Conversation

@b-client-vm
Copy link
Copy Markdown

Summary

Adds a user-level preference for how the Enter key behaves in the chat composer:

  • Enter to send (default, current behavior) — Shift+Enter inserts a newline.
  • Enter for new line — Cmd/Ctrl/Alt+Enter sends; Enter inserts a newline.

Persists via `localStorage` in a new `useChatInputPrefs` hook and is surfaced through a new Settings → Composition section. The placeholder text updates to hint at the submit shortcut when in modifier-submit mode.

Closes #599 (auto-expanding textarea, also mentioned in that issue, already exists in `CortexChatPanel`/`ChatComposer` so no change was needed for that item).

Where it's wired

  • `PortalComposer` (main agent chat) — passes `enterToSubmit` through to `` from `@spacedrive/ai`.
  • `CortexChatPanel` (new-agent dialog composer) — applies the same keydown logic directly.

Dependency

Requires the new `enterToSubmit` prop on `@spacedrive/ai`'s `ChatComposer`, added in:

That PR must be merged and a new `@spacedrive/ai` release published before this PR can be merged. The `interface/package.json` dependency on `@spacedrive/ai` (currently `^0.2.3`) will need a bump in a follow-up commit on this branch once the new version is published.

Test plan

  • Settings → Composition shows the two-option picker; selection persists across reloads.
  • Enter to send mode: Enter sends, Shift+Enter newlines, Cmd/Ctrl/Alt+Enter also sends.
  • Enter for new line mode: Enter inserts a newline; Cmd+Enter (mac), Ctrl+Enter, and Alt/Option+Enter send.
  • Both modes work in PortalComposer (main chat) and in the new-agent dialog (`CortexChatPanel`).
  • IME composition (Japanese/Chinese) — pressing Enter to commit a candidate does not submit.
  • No regressions to existing send button / placeholder text.

Adds a user-level preference for how the Enter key behaves in the
chat composer:
- Enter to send (default, current behavior) — Shift+Enter inserts a newline
- Enter for new line — Cmd/Ctrl/Alt+Enter sends

Persists via localStorage in a new useChatInputPrefs hook, surfaced
through a new Settings → Composition section. Wired through
PortalComposer (main chat) via the new `enterToSubmit` prop on
@spacedrive/ai's ChatComposer, and also applied to CortexChatPanel
(the new-agent dialog composer).

Closes spacedriveapp#599
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 13, 2026

Review Change Stack

Walkthrough

This PR adds a configurable Enter key behavior preference for chat input with persistent storage and a new settings UI section. Users can toggle between Enter-to-submit and Enter-for-newline modes; the preference syncs across tabs and is reflected in chat input placeholders and keyboard handling.

Changes

Enter key behavior preference and UI

Layer / File(s) Summary
Preference storage and state management
interface/src/hooks/useChatInputPrefs.ts
Introduces ChatInputPrefs interface and useChatInputPrefs hook that persist enterToSubmit to localStorage with SSR-safe reads, JSON error handling, and cross-tab synchronization via storage event listener.
Settings UI for composition preferences
interface/src/components/settings/CompositionSection.tsx, interface/src/components/settings/constants.ts, interface/src/components/settings/types.ts, interface/src/components/settings/index.ts, interface/src/routes/Settings.tsx
Adds CompositionSection component with toggle buttons for Enter key behavior; extends settings configuration with a composition section, re-exports the component, and routes rendering when activeSection is "composition".
Chat input integrations with preference hook
interface/src/components/CortexChatPanel.tsx, interface/src/components/portal/PortalComposer.tsx
Updates CortexChatPanel and PortalComposer to read prefs.enterToSubmit and conditionally treat Enter as submit or newline; gating send behavior on composing/Shift/modifiers and updating textarea placeholder text (including streaming state messages).

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'feat(interface): configurable Enter behavior in chat composer' clearly and specifically describes the main change—adding user-configurable Enter key behavior for the chat input.
Description check ✅ Passed The PR description thoroughly explains the feature (two Enter modes), how it persists, where it's integrated, dependencies, and a detailed test plan—all directly related to the changeset.
Linked Issues check ✅ Passed The PR implements the configurable Enter behavior objective from #599 completely; the auto-expanding textarea objective is noted as already existing and requiring no change.
Out of Scope Changes check ✅ Passed All changes are scoped to implementing the configurable Enter behavior preference and its settings UI; no unrelated modifications were detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
interface/src/components/settings/CompositionSection.tsx (1)

38-55: ⚡ Quick win

Add explicit button semantics for toggle options.

Line 38 should set type="button" and expose selected state (e.g., aria-pressed) so assistive tech can announce which mode is active.

Proposed diff
 						<button
 							key={String(opt.value)}
+							type="button"
 							onClick={() => setEnterToSubmit(opt.value)}
+							aria-pressed={active}
 							className={`flex flex-col items-start rounded-lg border p-4 text-left transition-colors ${
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@interface/src/components/settings/CompositionSection.tsx` around lines 38 -
55, In CompositionSection.tsx update the option button rendered for each opt
(the button that calls setEnterToSubmit(opt.value) and uses the active flag) to
include explicit button semantics: add type="button" to prevent accidental form
submission and add an accessible selected state such as aria-pressed={active}
(or aria-checked if you treat it like a toggle) so screen readers announce which
mode is active; ensure the same button element that renders
opt.title/opt.description uses these attributes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@interface/src/components/settings/CompositionSection.tsx`:
- Around line 38-55: In CompositionSection.tsx update the option button rendered
for each opt (the button that calls setEnterToSubmit(opt.value) and uses the
active flag) to include explicit button semantics: add type="button" to prevent
accidental form submission and add an accessible selected state such as
aria-pressed={active} (or aria-checked if you treat it like a toggle) so screen
readers announce which mode is active; ensure the same button element that
renders opt.title/opt.description uses these attributes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 900effc7-106f-424d-9ab9-e886accc19ce

📥 Commits

Reviewing files that changed from the base of the PR and between ac52277 and 68ff1ea.

📒 Files selected for processing (8)
  • interface/src/components/CortexChatPanel.tsx
  • interface/src/components/portal/PortalComposer.tsx
  • interface/src/components/settings/CompositionSection.tsx
  • interface/src/components/settings/constants.ts
  • interface/src/components/settings/index.ts
  • interface/src/components/settings/types.ts
  • interface/src/hooks/useChatInputPrefs.ts
  • interface/src/routes/Settings.tsx

- CompositionSection: add type="button" and aria-pressed to the
  Enter-behavior toggle so assistive tech can announce the active mode.
- CortexChatPanel: gate keyboard-triggered submit on canSend (matches
  the send button's enabled state and mirrors the upstream ChatComposer
  fix in spaceui#4).

Addresses CodeRabbit review on spacedriveapp#600.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@interface/src/components/CortexChatPanel.tsx`:
- Around line 216-219: The Enter-to-submit branch inside the key handler (where
prefs.enterToSubmit is checked) only ignores Shift+Enter but not
Alt/Option+Enter, so Alt+Enter still submits; update the condition in the
handler (the block referencing prefs.enterToSubmit and canSend/onSubmit) to also
return when event.altKey (Option on macOS) is true (e.g., if (event.shiftKey ||
event.altKey) return;) so Shift/Option+Enter inserts a newline instead of
submitting.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1c07bb44-a36f-4393-b6fd-274a5d70f37b

📥 Commits

Reviewing files that changed from the base of the PR and between 68ff1ea and be5f071.

📒 Files selected for processing (2)
  • interface/src/components/CortexChatPanel.tsx
  • interface/src/components/settings/CompositionSection.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • interface/src/components/settings/CompositionSection.tsx

Comment on lines +216 to +219
if (prefs.enterToSubmit) {
if (event.shiftKey) return;
event.preventDefault();
if (canSend) onSubmit();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Alt+Enter incorrectly submits in Enter-to-submit mode.

Line 217 only exempts Shift+Enter, so Alt+Enter currently submits. That conflicts with the documented mode-A behavior where Shift/Option+Enter should insert a newline.

Suggested patch
 		if (prefs.enterToSubmit) {
-			if (event.shiftKey) return;
+			if (event.shiftKey || event.altKey) return;
 			event.preventDefault();
 			if (canSend) onSubmit();
 		} else if (hasSubmitModifier) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (prefs.enterToSubmit) {
if (event.shiftKey) return;
event.preventDefault();
if (canSend) onSubmit();
if (prefs.enterToSubmit) {
if (event.shiftKey || event.altKey) return;
event.preventDefault();
if (canSend) onSubmit();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@interface/src/components/CortexChatPanel.tsx` around lines 216 - 219, The
Enter-to-submit branch inside the key handler (where prefs.enterToSubmit is
checked) only ignores Shift+Enter but not Alt/Option+Enter, so Alt+Enter still
submits; update the condition in the handler (the block referencing
prefs.enterToSubmit and canSend/onSubmit) to also return when event.altKey
(Option on macOS) is true (e.g., if (event.shiftKey || event.altKey) return;) so
Shift/Option+Enter inserts a newline instead of submitting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Chat input: configurable Enter behavior + auto-expanding textarea

2 participants