ux: textarea auto-grow, preview toggle in toolbar, prose-lg on richtext, no more bottom preview btn

This commit is contained in:
Antigravity
2026-05-07 22:52:51 +00:00
parent 01390ebb5b
commit 24b5d6bdac

View File

@@ -258,6 +258,14 @@ export function NoteEditor({ note, readOnly = false, onClose, fullPage = false }
return () => document.removeEventListener('paste', handlePaste, { capture: true } as any)
}, [t])
// Auto-grow textarea as content grows
useEffect(() => {
const el = textareaRef.current
if (!el) return
el.style.height = 'auto'
el.style.height = Math.max(el.scrollHeight, 280) + 'px'
}, [content])
const handleRemoveImage = (index: number) => {
const removedUrl = images[index]
setImages(images.filter((_, i) => i !== index))
@@ -700,6 +708,23 @@ export function NoteEditor({ note, readOnly = false, onClose, fullPage = false }
compact
/>
{/* Preview toggle — only for text/markdown, in toolbar where it's visible */}
{(noteType === 'text' || noteType === 'markdown') && !readOnly && (
<button
onClick={() => setShowMarkdownPreview(v => !v)}
title={showMarkdownPreview ? 'Revenir à l\'édition' : 'Prévisualiser le rendu'}
className={cn(
'flex items-center gap-2 px-3 py-1.5 rounded-full border transition-all duration-300 text-xs font-medium',
showMarkdownPreview
? 'bg-foreground text-background border-foreground'
: 'border-black/20 dark:border-white/20 text-foreground hover:bg-black/5 dark:hover:bg-white/5'
)}
>
<Eye size={16} />
<span>{showMarkdownPreview ? 'Éditer' : 'Aperçu'}</span>
</button>
)}
{/* AI — rounded-full, exact prototype style */}
<button
onClick={() => { setAiOpen(v => !v); setInfoOpen(false) }}
@@ -811,23 +836,25 @@ export function NoteEditor({ note, readOnly = false, onClose, fullPage = false }
)}
{/* Content area — max-w-2xl, like prototype */}
<div className="max-w-2xl mx-auto space-y-8 pb-32">
<div className="max-w-2xl mx-auto pb-32">
{noteType === 'richtext' ? (
<RichTextEditor
content={content}
onChange={(v) => { setContent(v); setIsDirty(true) }}
className="min-h-[60vh] text-lg font-light leading-relaxed text-foreground/80"
onImageUpload={uploadImageFile}
/>
<div className="prose prose-lg dark:prose-invert max-w-none [&_.notion-editor]:min-h-[280px]">
<RichTextEditor
content={content}
onChange={(v) => { setContent(v); setIsDirty(true) }}
className="min-h-[280px] text-lg font-light leading-relaxed"
onImageUpload={uploadImageFile}
/>
</div>
) : (noteType === 'markdown' || noteType === 'text') && showMarkdownPreview ? (
<div
className="min-h-[300px] cursor-text prose prose-lg dark:prose-invert max-w-none leading-relaxed"
className="min-h-[280px] cursor-text prose prose-lg dark:prose-invert max-w-none leading-relaxed"
onClick={() => !readOnly && setShowMarkdownPreview(false)}
>
<MarkdownContent content={content} />
{!readOnly && (
<p className="text-[11px] text-foreground/30 mt-6 select-none not-prose">
Click to edit
<p className="text-[11px] text-foreground/30 mt-8 select-none not-prose italic">
Cliquez pour éditer
</p>
)}
</div>
@@ -836,22 +863,13 @@ export function NoteEditor({ note, readOnly = false, onClose, fullPage = false }
<textarea
ref={textareaRef}
dir="auto"
placeholder={t('notes.takeNote') || "Type '/' for commands"}
placeholder={t('notes.takeNote') || "Commencez à écrire… tapez '/' pour les commandes"}
value={content}
onFocus={() => setShowMarkdownPreview(false)}
onChange={(e) => { setContent(e.target.value); setIsDirty(true) }}
disabled={readOnly}
className="w-full min-h-[60vh] border-0 outline-none px-0 bg-transparent text-lg leading-relaxed font-light resize-none placeholder:text-foreground/20 text-foreground/80"
className="w-full min-h-[280px] border-0 outline-none px-0 bg-transparent text-lg leading-relaxed font-light resize-none overflow-hidden placeholder:text-foreground/20 text-foreground/80"
/>
{content && !readOnly && (
<button
type="button"
onClick={() => setShowMarkdownPreview(true)}
className="mt-2 text-[11px] text-foreground/40 hover:text-foreground flex items-center gap-1.5 transition-colors"
>
<Eye className="h-3 w-3" /> Preview
</button>
)}
{!readOnly && (
<MarkdownSlashCommands
textareaRef={textareaRef as React.RefObject<HTMLTextAreaElement>}