Skip to content

feat: migrate Composer from textarea to Lexical for inline mention chips #55

Description

@chuks-qua

Description

The composer currently uses a plain <textarea> with a transparent CSS overlay (TextOverlay) behind it for token highlighting. This approach can render colored backgrounds for @file and /command tokens but cannot render inline icons or interactive chips — the textarea only renders plain text.

T3 Code uses Lexical (a rich text editor framework by Meta) which allows rendering custom DecoratorNode / TextNode subclasses as real DOM elements inline. Their ComposerMentionNode renders file mentions as chips with:

  • VSCode file-type icons (loaded from jsDelivr CDN via vscode-icons manifest)
  • Basename label (e.g., just `index.ts` not the full path)
  • Chip styling: `inline-flex rounded-md border bg-accent/40 px-1.5`
  • Atomic behavior: cursor jumps over it, backspace deletes the whole chip

What needs to change

Remove

  • `TextOverlay.tsx` — replaced by Lexical's native node rendering
  • Transparent overlay scroll sync logic in Composer
  • `COMBINED_TOKEN_RE` and `HIGHLIGHT_RE` from `file-tags.ts` (overlay-only)

Add

  • `@lexical/react` dependency
  • `ComposerPromptEditor.tsx` — Lexical wrapper with `PlainTextPlugin`, `HistoryPlugin`, `OnChangePlugin`
  • `ComposerMentionNode` — custom Lexical `TextNode` for `@file` mentions (renders chip with icon)
  • `ComposerSlashCommandNode` — custom Lexical `TextNode` for `/command` tokens (renders chip with namespace color)
  • VSCode icon resolution (CDN-based, like T3's `vscode-icons.ts`)
  • Dual cursor model: collapsed cursor (for storage) vs expanded cursor (for trigger detection) — see T3's PR feat: polish subagent activity workspace #936

Modify

  • `Composer.tsx` — replace `<textarea>` with ``, adapt all keyboard handlers
  • `useSlashCommand.ts` — adapt trigger detection from regex-on-textarea-value to Lexical editor state
  • `useFileAutocomplete.ts` — same adaptation
  • `FileTagPopup.tsx` / `SlashCommandPopup.tsx` — positioning may change (anchor to Lexical selection rect instead of textarea bounding rect)

Reference implementation

  • T3 Code PR #142 — original Lexical composer with file mention pills
  • T3 Code PR #936 — cursor bug fixes (expanded vs collapsed cursor model)
  • Key files: `ComposerPromptEditor.tsx`, `composerInlineChip.ts`, `composer-editor-mentions.ts`, `composer-logic.ts`, `vscode-icons.ts`

Current state (what we have now)

  • Extension-aware lucide icons in file picker dropdown (`file-icons.tsx`)
  • Colored background chips via CSS overlay for `@file` (blue), `/skill` (green), `/m:plan` (primary), `/plugin:cmd` (orange)
  • These work but are limited by the textarea constraint — no inline icons, no atomic chip behavior

🤖 Generated with Claude Code

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions