diff --git a/src/App.css b/src/App.css index d6f2b7b..672868c 100644 --- a/src/App.css +++ b/src/App.css @@ -143,6 +143,47 @@ word-break: break-word; } +.app__action--small { + padding: 0.4rem 0.9rem; + font-size: 0.9rem; +} + +.app__action:disabled { + opacity: 0.5; + cursor: not-allowed; + transform: none; +} + +.app__panel .app__action--ghost { + color: #93c5fd; + background: rgba(59, 130, 246, 0.18); +} + +.app__md-input { + box-sizing: border-box; + width: 100%; + min-height: 200px; + resize: vertical; + padding: 0.75rem; + border: 1px solid rgba(148, 163, 184, 0.3); + border-radius: 0.5rem; + background: rgba(15, 23, 42, 0.6); + color: inherit; + font-family: "JetBrains Mono", "Fira Code", monospace; + font-size: 0.9rem; + line-height: 1.45; +} + +.app__md-input::placeholder { + color: rgba(148, 163, 184, 0.7); +} + +.app__md-input:focus { + outline: none; + border-color: #3b82f6; + box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.35); +} + .app__error { margin: 0; color: #fca5a5; @@ -260,6 +301,21 @@ html.dark .app__panel { box-shadow: inset 0 0 0 1px rgba(64, 64, 64, 0.5); } +html.dark .app__md-input { + background: #0a0a0a; + border-color: #404040; +} + +html.dark .app__md-input:focus { + border-color: #6366f1; + box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.35); +} + +html.dark .app__panel .app__action--ghost { + color: #818cf8; + background: rgba(99, 102, 241, 0.15); +} + html.dark .app__panel--light { background: #262626; color: #fafafa; diff --git a/src/App.tsx b/src/App.tsx index f6fc25e..bbf1200 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -523,6 +523,8 @@ function App() { "idle", ); const [darkMode, setDarkMode] = useState(false); + const [markdownInput, setMarkdownInput] = useState(""); + const [inputError, setInputError] = useState(null); useEffect(() => { document.documentElement.classList.toggle("dark", darkMode); @@ -657,6 +659,21 @@ function App() { if (id) focusStepField(editor, id); }; + // Load the pasted Markdown as the whole document, the way a host app does on + // initial load (unlike pasting into the editor, which goes through the paste handler). + const handleApplyMarkdown = () => { + try { + const blocks = markdownToBlocks(markdownInput); + editor.replaceBlocks( + editor.document, + blocks.length > 0 ? blocks : [{ type: "paragraph" }], + ); + setInputError(null); + } catch (error) { + setInputError(error instanceof Error ? error.message : String(error)); + } + }; + const handleCopyMarkdown = async () => { if (conversionError) { return; @@ -782,6 +799,49 @@ function App() {