From 6bc67a3118765a998cddd9a703d1a789c5abf9d9 Mon Sep 17 00:00:00 2001 From: drelich Date: Mon, 6 Apr 2026 16:15:43 +0200 Subject: [PATCH] Add interactive task lists and table insertion to markdown editor - Enable task list checkbox toggling in preview mode with live content updates - Add task list and table insertion buttons to InsertToolbar - Implement smart block snippet insertion with automatic newline handling - Add horizontal scroll wrapper for wide tables in preview - Fix editor scroll position preservation during content updates - Use useLayoutEffect to prevent scroll jumps when textarea auto-resizes - Update task list styling --- src/components/InsertToolbar.tsx | 38 +++++- src/components/NoteEditor.tsx | 214 ++++++++++++++++++++++++++----- src/components/PrintView.tsx | 22 ++++ src/index.css | 12 +- src/printExport.ts | 22 ++++ 5 files changed, 275 insertions(+), 33 deletions(-) diff --git a/src/components/InsertToolbar.tsx b/src/components/InsertToolbar.tsx index 7a29145..03b4952 100644 --- a/src/components/InsertToolbar.tsx +++ b/src/components/InsertToolbar.tsx @@ -3,6 +3,8 @@ import { useEffect, useState, useRef, RefObject } from 'react'; interface InsertToolbarProps { textareaRef: RefObject; onInsertLink: (text: string, url: string) => void; + onInsertTodoItem: () => void; + onInsertTable: () => void; onInsertFile: () => void; isUploading?: boolean; } @@ -13,7 +15,7 @@ interface LinkModalState { url: string; } -export function InsertToolbar({ textareaRef, onInsertLink, onInsertFile, isUploading }: InsertToolbarProps) { +export function InsertToolbar({ textareaRef, onInsertLink, onInsertTodoItem, onInsertTable, onInsertFile, isUploading }: InsertToolbarProps) { const [position, setPosition] = useState<{ top: number; left: number } | null>(null); const [isVisible, setIsVisible] = useState(false); const [linkModal, setLinkModal] = useState({ isOpen: false, text: '', url: '' }); @@ -58,7 +60,7 @@ export function InsertToolbar({ textareaRef, onInsertLink, onInsertFile, isUploa const left = textareaRect.left + paddingLeft + (currentLineText.length * charWidth) + 20; // Keep toolbar within viewport - const toolbarWidth = 100; + const toolbarWidth = 196; const adjustedLeft = Math.min(left, window.innerWidth - toolbarWidth - 20); let adjustedTop = top - 16; // Center vertically with cursor line @@ -137,6 +139,16 @@ export function InsertToolbar({ textareaRef, onInsertLink, onInsertFile, isUploa setIsVisible(false); }; + const handleTodoClick = () => { + onInsertTodoItem(); + setIsVisible(false); + }; + + const handleTableClick = () => { + onInsertTable(); + setIsVisible(false); + }; + if (!isVisible || !position) return null; // Link Modal @@ -217,6 +229,28 @@ export function InsertToolbar({ textareaRef, onInsertLink, onInsertFile, isUploa + + + +