mirror of
https://github.com/davidkaya/aryx.git
synced 2026-08-07 04:08:45 +02:00
feat: replace textarea with Lexical WYSIWYG markdown composer
Replace the plain <textarea> in ChatPane with a full WYSIWYG markdown composer built on Lexical 0.42.0. Composer features: - Rich text editing with inline formatting (bold, italic, code) - Block-level elements: headings, bullet/numbered lists, code blocks, blockquotes, links via markdown shortcuts (e.g. ## , - , \\\) - Formatting toolbar with active-state indicators - Markdown paste auto-import when the editor is empty - Enter to send, Shift+Enter for newline (matches prior behavior) - Disabled state syncs with session busy/config states - Serializes to markdown on submit via the backend helpers Files: - New: MarkdownComposer.tsx (Lexical editor, toolbar, internal plugins) - Modified: ChatPane.tsx (swap textarea for MarkdownComposer, simplify state) - Modified: styles.css (add markdown composer theme classes) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -140,6 +140,112 @@ textarea {
|
||||
max-height: 200px;
|
||||
}
|
||||
|
||||
/* ── Markdown composer (Lexical) ────────────────────────── */
|
||||
|
||||
.markdown-composer-content {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.markdown-composer-editable {
|
||||
min-height: 40px;
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
padding: 8px 48px 8px 16px;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
color: #f4f4f5;
|
||||
outline: none;
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.markdown-composer-editable[contenteditable="false"] {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.markdown-composer-placeholder {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
left: 16px;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
color: #52525b;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
/* Paragraphs */
|
||||
.mc-p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Headings */
|
||||
.mc-h1, .mc-h2, .mc-h3 {
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.mc-h1 { font-size: 1.1em; }
|
||||
.mc-h2 { font-size: 1.05em; }
|
||||
.mc-h3 { font-size: 1em; }
|
||||
|
||||
/* Inline formatting */
|
||||
.mc-bold { font-weight: 600; }
|
||||
.mc-italic { font-style: italic; }
|
||||
.mc-strikethrough { text-decoration: line-through; }
|
||||
.mc-underline { text-decoration: underline; }
|
||||
.mc-inline-code {
|
||||
background: rgba(63, 63, 70, 0.6);
|
||||
border-radius: 3px;
|
||||
padding: 1px 4px;
|
||||
font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
/* Lists */
|
||||
.mc-ul {
|
||||
list-style-type: disc;
|
||||
padding-left: 1.5em;
|
||||
margin: 2px 0;
|
||||
}
|
||||
.mc-ol {
|
||||
list-style-type: decimal;
|
||||
padding-left: 1.5em;
|
||||
margin: 2px 0;
|
||||
}
|
||||
.mc-li {
|
||||
margin: 1px 0;
|
||||
}
|
||||
|
||||
/* Blockquote */
|
||||
.mc-blockquote {
|
||||
border-left: 3px solid #3f3f46;
|
||||
padding-left: 0.75em;
|
||||
color: #a1a1aa;
|
||||
margin: 2px 0;
|
||||
}
|
||||
|
||||
/* Code block */
|
||||
.mc-code-block {
|
||||
background: rgba(24, 24, 27, 0.8);
|
||||
border: 1px solid #27272a;
|
||||
border-radius: 6px;
|
||||
padding: 8px 12px;
|
||||
font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
|
||||
font-size: 0.9em;
|
||||
white-space: pre-wrap;
|
||||
tab-size: 2;
|
||||
margin: 4px 0;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
/* Link */
|
||||
.mc-link {
|
||||
color: #818cf8;
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 2px;
|
||||
}
|
||||
|
||||
/* React Flow dark theme overrides */
|
||||
.react-flow__node {
|
||||
font-family: inherit;
|
||||
|
||||
Reference in New Issue
Block a user