feat: Markdown 뷰어/편집기 개선
- startEdit(): extracted_text || rawMarkdown fallback - split editor → 편집/미리보기 탭 전환 방식 - GitHub Dark 스타일 markdown-body CSS (테이블/코드/인용/리스트) - prose 클래스 → markdown-body로 교체 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -37,3 +37,31 @@ body {
|
|||||||
::-webkit-scrollbar { width: 6px; }
|
::-webkit-scrollbar { width: 6px; }
|
||||||
::-webkit-scrollbar-track { background: var(--bg); }
|
::-webkit-scrollbar-track { background: var(--bg); }
|
||||||
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
|
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
|
||||||
|
|
||||||
|
/* Markdown 렌더링 (GitHub Dark 스타일) */
|
||||||
|
.markdown-body {
|
||||||
|
color: var(--text);
|
||||||
|
line-height: 1.7;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.markdown-body h1 { font-size: 1.6em; font-weight: 700; margin: 1.5em 0 0.5em; padding-bottom: 0.3em; border-bottom: 1px solid var(--border); }
|
||||||
|
.markdown-body h2 { font-size: 1.3em; font-weight: 600; margin: 1.3em 0 0.4em; padding-bottom: 0.2em; border-bottom: 1px solid var(--border); }
|
||||||
|
.markdown-body h3 { font-size: 1.1em; font-weight: 600; margin: 1.2em 0 0.3em; }
|
||||||
|
.markdown-body h4 { font-size: 1em; font-weight: 600; margin: 1em 0 0.2em; }
|
||||||
|
.markdown-body p { margin: 0.6em 0; }
|
||||||
|
.markdown-body ul, .markdown-body ol { padding-left: 1.5em; margin: 0.5em 0; }
|
||||||
|
.markdown-body li { margin: 0.2em 0; }
|
||||||
|
.markdown-body li > ul, .markdown-body li > ol { margin: 0.1em 0; }
|
||||||
|
.markdown-body blockquote { border-left: 3px solid var(--accent); padding: 0.5em 1em; margin: 0.8em 0; color: var(--text-dim); background: var(--surface); border-radius: 0 4px 4px 0; }
|
||||||
|
.markdown-body code { background: var(--surface); padding: 0.15em 0.4em; border-radius: 3px; font-size: 0.9em; font-family: 'SF Mono', Menlo, monospace; }
|
||||||
|
.markdown-body pre { background: var(--surface); padding: 1em; border-radius: 6px; overflow-x: auto; margin: 0.8em 0; border: 1px solid var(--border); }
|
||||||
|
.markdown-body pre code { background: none; padding: 0; }
|
||||||
|
.markdown-body table { border-collapse: collapse; width: 100%; margin: 0.8em 0; }
|
||||||
|
.markdown-body th, .markdown-body td { border: 1px solid var(--border); padding: 0.5em 0.8em; text-align: left; font-size: 0.9em; }
|
||||||
|
.markdown-body th { background: var(--surface); font-weight: 600; }
|
||||||
|
.markdown-body tr:nth-child(even) { background: rgba(255,255,255,0.02); }
|
||||||
|
.markdown-body hr { border: none; border-top: 1px solid var(--border); margin: 1.5em 0; }
|
||||||
|
.markdown-body a { color: var(--accent); text-decoration: none; }
|
||||||
|
.markdown-body a:hover { text-decoration: underline; }
|
||||||
|
.markdown-body strong { font-weight: 600; }
|
||||||
|
.markdown-body img { max-width: 100%; border-radius: 4px; }
|
||||||
|
|||||||
@@ -69,10 +69,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function startEdit() {
|
function startEdit() {
|
||||||
editContent = fullDoc?.extracted_text || '';
|
editContent = fullDoc?.extracted_text || rawMarkdown || '';
|
||||||
editMode = true;
|
editMode = true;
|
||||||
|
editTab = 'edit';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let editTab = $state('edit'); // 'edit' | 'preview'
|
||||||
|
|
||||||
async function saveContent() {
|
async function saveContent() {
|
||||||
saving = true;
|
saving = true;
|
||||||
try {
|
try {
|
||||||
@@ -155,19 +158,32 @@
|
|||||||
{:else if fullDoc}
|
{:else if fullDoc}
|
||||||
{#if viewerType === 'markdown'}
|
{#if viewerType === 'markdown'}
|
||||||
{#if editMode}
|
{#if editMode}
|
||||||
<!-- Markdown split editor -->
|
<!-- Markdown 편집 (탭 전환) -->
|
||||||
<div class="flex h-full">
|
<div class="flex flex-col h-full">
|
||||||
<textarea
|
<div class="flex gap-1 px-3 py-1 border-b border-[var(--border)] shrink-0">
|
||||||
bind:value={editContent}
|
<button
|
||||||
class="w-1/2 h-full p-4 bg-[var(--bg)] text-[var(--text)] text-sm font-mono resize-none outline-none border-r border-[var(--border)]"
|
onclick={() => editTab = 'edit'}
|
||||||
spellcheck="false"
|
class="px-3 py-1 text-xs rounded-t {editTab === 'edit' ? 'bg-[var(--surface)] text-[var(--text)]' : 'text-[var(--text-dim)]'}"
|
||||||
></textarea>
|
>편집</button>
|
||||||
<div class="w-1/2 h-full p-4 overflow-auto prose prose-invert prose-sm max-w-none">
|
<button
|
||||||
{@html marked(editContent)}
|
onclick={() => editTab = 'preview'}
|
||||||
|
class="px-3 py-1 text-xs rounded-t {editTab === 'preview' ? 'bg-[var(--surface)] text-[var(--text)]' : 'text-[var(--text-dim)]'}"
|
||||||
|
>미리보기</button>
|
||||||
</div>
|
</div>
|
||||||
|
{#if editTab === 'edit'}
|
||||||
|
<textarea
|
||||||
|
bind:value={editContent}
|
||||||
|
class="flex-1 w-full p-4 bg-[var(--bg)] text-[var(--text)] text-sm font-mono resize-none outline-none"
|
||||||
|
spellcheck="false"
|
||||||
|
></textarea>
|
||||||
|
{:else}
|
||||||
|
<div class="flex-1 overflow-auto p-4 markdown-body">
|
||||||
|
{@html marked(editContent)}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="p-4 prose prose-invert prose-sm max-w-none">
|
<div class="p-4 markdown-body">
|
||||||
{@html marked(fullDoc.extracted_text || rawMarkdown || '*텍스트 추출 대기 중*')}
|
{@html marked(fullDoc.extracted_text || rawMarkdown || '*텍스트 추출 대기 중*')}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
Reference in New Issue
Block a user