라이브 작성 블록 렌더링과 발행 시각 보정

This commit is contained in:
2026-07-02 16:01:45 +09:00
parent 0576069427
commit 7f20949669
15 changed files with 222 additions and 20 deletions

View File

@@ -1545,6 +1545,12 @@ watch(publishStatus, (next) => {
}
})
watch(() => form.status, (next) => {
if (next === 'published' && !toIsoDateTime(form.publishedAt)) {
form.publishedAt = toDateTimeLocalValue(new Date().toISOString())
}
})
watch(serializedPostFingerprint, () => {
if (!import.meta.client) {
return

View File

@@ -109,6 +109,7 @@ const onBodyInput = (payload) => {
<ContentMarkdownEditableInline
block-class="content-markdown-callout-editor__body min-w-0 text-[15px] leading-8 text-[var(--site-text)]"
enter-mode="multiline"
block-markdown
arrow-exit-creates-line
preserve-empty-line-on-full-delete
:source-line="bodySourceLine"

View File

@@ -2,6 +2,7 @@
import {
getEditableCaretOffset,
markdownInlineToHtml,
markdownMultilineBlockToHtml,
markdownMultilineInlineToHtml,
readEditableTextFromElement,
setEditableCaretOffset
@@ -96,6 +97,11 @@ const props = defineProps({
type: Boolean,
default: false
},
/** true면 멀티라인 본문 안의 목록 같은 블록 문법도 라이브 표시한다. */
blockMarkdown: {
type: Boolean,
default: false
},
/** 전체 선택 삭제 시 비어 있는 원본 줄을 보존할지 여부 */
preserveEmptyLineOnFullDelete: {
type: Boolean,
@@ -167,6 +173,12 @@ const toEditorHtml = () => markdownInlineToHtml(props.modelValue.replace(/\n/g,
*/
const toMultilineEditorHtml = () => markdownMultilineInlineToHtml(props.modelValue)
/**
* modelValue를 블록 마크다운 포함 멀티라인 편집용 HTML로 변환한다.
* @returns {string} HTML
*/
const toMultilineBlockEditorHtml = () => markdownMultilineBlockToHtml(props.modelValue)
/**
* plainText 모드용 편집 텍스트를 만든다.
* @param {string} value - 본문
@@ -197,7 +209,7 @@ const syncEditorHtml = (options = {}) => {
}
rootRef.value.innerHTML = resolvedEnterMode.value === 'multiline'
? toMultilineEditorHtml()
? (props.blockMarkdown ? toMultilineBlockEditorHtml() : toMultilineEditorHtml())
: toEditorHtml()
}
@@ -1551,6 +1563,22 @@ defineExpose({ focusEditor, readEditorValue })
color: #fff;
}
.content-markdown-editable-inline :deep(ul),
.content-markdown-editable-inline :deep(ol) {
margin: 0.35rem 0;
padding-left: 1.25rem;
}
.content-markdown-editable-inline :deep(li) {
margin: 0.15rem 0;
padding-left: 0.15rem;
}
.content-markdown-editable-inline :deep(li::marker) {
color: #2eb6ea;
font-weight: 700;
}
.content-markdown-editable-inline :deep([data-inline-color='gray']) {
color: var(--site-muted);
}

View File

@@ -3193,6 +3193,7 @@ onBeforeUnmount(() => {
block-class="content-markdown-renderer__quote-line"
:model-value="block.text"
enter-mode="multiline"
block-markdown
arrow-exit-creates-line
preserve-empty-line-on-full-delete
empty-markdown-line="> "
@@ -3343,7 +3344,7 @@ onBeforeUnmount(() => {
:title="block.title"
:background="block.calloutBackground"
>
<ContentMarkdownInlineSegments :text="block.text" multiline />
<ContentMarkdownRenderer :content="block.text" />
</ProseCallout>
<ContentMarkdownToggleEditor
v-else-if="block.type === 'toggle' && interactive"
@@ -3358,7 +3359,7 @@ onBeforeUnmount(() => {
@delete-line="onDeleteLine"
/>
<ProseToggle v-else-if="block.type === 'toggle'" :title="block.title || '더 보기'" :default-open="block.defaultOpen" animated>
<ContentMarkdownInlineSegments :text="block.text" />
<ContentMarkdownRenderer :content="block.text" />
</ProseToggle>
<ProseBookmark
v-else-if="block.type === 'bookmark' && block.meta.url"

View File

@@ -136,7 +136,7 @@ const onExitBelow = (payload) => {
block-class="content-markdown-toggle-editor__body min-h-[3rem] outline-none"
enter-mode="multiline"
navigation-scope="parent"
plain-text
block-markdown
arrow-exit-creates-line
:source-line="bodySourceLine"
:source-line-count="String(modelValue ?? '').split('\n').length"

View File

@@ -62,7 +62,10 @@ const toggleOpen = () => {
</svg>
</button>
<div class="prose-toggle__title min-w-0 flex-1 text-[15px] font-semibold leading-7 text-[var(--site-text)]">
<div
class="prose-toggle__title min-w-0 flex-1 cursor-pointer text-[15px] font-semibold leading-7 text-[var(--site-text)]"
@click="toggleOpen"
>
<slot name="title">
{{ title || '더 보기' }}
</slot>