style: strip the multi-line composer down to a bare editor #3

Merged
adrianbonpin merged 1 commits from feat/minimal-composer into prod 2026-10-03 20:45:30 +00:00
+28 -10
View File
@@ -1,14 +1,34 @@
import { useNavigation } from "@vicinae/api";
import { Form, Action, ActionPanel, Icon } from "@vicinae/api";
import { Action, ActionPanel, Form, Icon, useNavigation } from "@vicinae/api";
import { useState } from "react";
/**
* The multi-line composer.
*
* This exists because the launcher's search bar is single-line and there is no
* API to change that. Pressing ⌘↩ in the chat view pushes this view, where a
* real multi-line text area gives the behaviour people expect from a chat box:
* Return inserts a newline, and ⌘↩ sends.
* This view exists because the launcher's search bar is single-line and there
* is no API to change that. Pressing ⌘↩ in the chat view pushes this view, where
* a real multi-line text area gives the behaviour people expect from a chat box:
* Return inserts a newline, ⌘↩ sends.
*
* It is deliberately stripped down to a single bare editor:
*
* - no field label, so nothing competes with the text itself
* - no description block, because the action bar already renders "Send ⌘↩"
* next to the button, which documents the shortcut without a paragraph
* - the placeholder is one short line rather than an instructions sentence
*
* ## The width limit
*
* A `Form.TextArea` cannot be made truly full-width from the extension API.
* Vicinae always renders it inside its `FormField` component
* (`ExtensionFormView.qml` → `textareaFieldComp`), and `FormField.qml` always
* lays out as three columns with proportional widths 2 / 5 / 2 — a label
* gutter, the editor, and an empty right spacer. That leaves roughly five
* ninths of the width for the editor, and the spacer stays even when there is
* no label. None of it is reachable from the extension side.
*
* So the only lever here is removing clutter, not reclaiming width. If Vicinae
* ever exposes a label-less or full-width field variant, this is the file to
* simplify further.
*/
export interface ComposeFormProps {
initialValue: string;
@@ -21,7 +41,7 @@ export function ComposeForm({ initialValue, onSubmit }: ComposeFormProps) {
return (
<Form
navigationTitle="Compose message"
navigationTitle="Compose"
actions={
<ActionPanel>
<Action.SubmitForm
@@ -46,13 +66,11 @@ export function ComposeForm({ initialValue, onSubmit }: ComposeFormProps) {
>
<Form.TextArea
id="prompt"
title="Message"
placeholder="Ask Lam anything. Return starts a new line."
placeholder="Ask Lam anything…"
defaultValue={initialValue}
error={error}
autoFocus
/>
<Form.Description title="Keyboard" text="Return — new line · ⌘↩ — send" />
</Form>
);
}