인용 블록 색상과 라이브 설정 패널 정리
This commit is contained in:
@@ -1,6 +1,12 @@
|
||||
<script setup>
|
||||
import { getImageAltAttribute, getImageDefaultAltLabel } from '../../lib/markdown-image.js'
|
||||
import { CALLOUT_BACKGROUND_OPTIONS, CALLOUT_EMOJI_OPTIONS } from '../../lib/markdown-callout.js'
|
||||
import {
|
||||
CALLOUT_BACKGROUND_OPTIONS,
|
||||
CALLOUT_EMOJI_OPTIONS,
|
||||
QUOTE_BACKGROUND_LABELS,
|
||||
QUOTE_BACKGROUND_OPTIONS,
|
||||
QUOTE_BACKGROUND_SWATCHES
|
||||
} from '../../lib/markdown-callout.js'
|
||||
|
||||
const props = defineProps({
|
||||
/** 패널 표시 여부 */
|
||||
@@ -66,6 +72,20 @@ const getBackgroundLabel = (background) => backgroundLabels[background] || backg
|
||||
*/
|
||||
const getBackgroundSwatch = (background) => backgroundSwatches[background] || 'rgba(100,116,139,0.28)'
|
||||
|
||||
/**
|
||||
* 인용 배경 라벨을 반환한다.
|
||||
* @param {string} background - 배경 키
|
||||
* @returns {string} 배경 라벨
|
||||
*/
|
||||
const getQuoteBackgroundLabel = (background) => QUOTE_BACKGROUND_LABELS[background] || background
|
||||
|
||||
/**
|
||||
* 인용 배경 스와치를 반환한다.
|
||||
* @param {string} background - 배경 키
|
||||
* @returns {string} CSS 배경
|
||||
*/
|
||||
const getQuoteBackgroundSwatch = (background) => QUOTE_BACKGROUND_SWATCHES[background] || QUOTE_BACKGROUND_SWATCHES.gray
|
||||
|
||||
/**
|
||||
* 블록 종류 라벨
|
||||
* @returns {string}
|
||||
@@ -212,7 +232,7 @@ const onPanelFocusOut = (event) => {
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<button
|
||||
v-for="background in CALLOUT_BACKGROUND_OPTIONS"
|
||||
v-for="background in QUOTE_BACKGROUND_OPTIONS"
|
||||
:key="`quote-background-${background}`"
|
||||
class="flex items-center gap-2 rounded border px-3 py-2 text-left text-xs font-semibold transition"
|
||||
:class="panel.quoteBackground === background ? 'border-[#15171a] bg-white text-[#15171a]' : 'border-[#dce0e5] bg-[#fafafa] text-[#657080] hover:bg-white'"
|
||||
@@ -221,10 +241,10 @@ const onPanelFocusOut = (event) => {
|
||||
>
|
||||
<span
|
||||
class="size-5 shrink-0 rounded-full border border-black/5"
|
||||
:style="{ background: getBackgroundSwatch(background) }"
|
||||
:style="{ background: getQuoteBackgroundSwatch(background) }"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<span>{{ getBackgroundLabel(background) }}</span>
|
||||
<span>{{ getQuoteBackgroundLabel(background) }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
parseSlashInput,
|
||||
resolveSlashCommand
|
||||
} from '../../lib/markdown-slash-commands.js'
|
||||
import { buildCalloutOpenerLine, CALLOUT_BACKGROUND_OPTIONS } from '../../lib/markdown-callout.js'
|
||||
import { buildCalloutOpenerLine, CALLOUT_BACKGROUND_OPTIONS, QUOTE_BACKGROUND_OPTIONS } from '../../lib/markdown-callout.js'
|
||||
import { buildCodeFenceOpener } from '../../lib/markdown-code-block.js'
|
||||
import { buildToggleOpenerLine } from '../../lib/markdown-toggle.js'
|
||||
import { getTextareaCaretCoordinates } from '../../lib/textarea-caret-coordinates.js'
|
||||
@@ -219,6 +219,49 @@ const syncBlockPanelState = () => {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 라이브 모드 포커스 줄을 기준으로 블록 패널을 동기화한다.
|
||||
* @param {number} sourceLine - 원본 마크다운 줄(0-based)
|
||||
* @returns {void}
|
||||
*/
|
||||
const handleLiveLineFocus = async (sourceLine) => {
|
||||
const nextLine = Number(sourceLine)
|
||||
|
||||
if (!Number.isInteger(nextLine) || nextLine < 0) {
|
||||
return
|
||||
}
|
||||
|
||||
activeLogicalLineIndex.value = nextLine
|
||||
isTextareaFocused.value = false
|
||||
isTextComposing.value = false
|
||||
|
||||
await nextTick()
|
||||
|
||||
if (activeBlockContext.value) {
|
||||
lastStableBlockContext.value = activeBlockContext.value
|
||||
isBlockPanelEngaged.value = true
|
||||
} else {
|
||||
isBlockPanelEngaged.value = false
|
||||
}
|
||||
|
||||
syncBlockPanelState()
|
||||
}
|
||||
|
||||
/**
|
||||
* 라이브 모드 포커스가 블록·패널 밖으로 나가면 패널을 닫는다.
|
||||
* @returns {void}
|
||||
*/
|
||||
const handleLiveLineBlur = () => {
|
||||
blockPanelFocusTimer = window.setTimeout(() => {
|
||||
if (isMediaPickerOpen.value || isFocusInBlockPanel() || isFocusInMediaPicker()) {
|
||||
return
|
||||
}
|
||||
|
||||
isBlockPanelEngaged.value = false
|
||||
syncBlockPanelState()
|
||||
}, 0)
|
||||
}
|
||||
|
||||
watch(activeBlockContext, (context) => {
|
||||
if (context) {
|
||||
lastStableBlockContext.value = context
|
||||
@@ -2136,7 +2179,7 @@ const updateActiveQuoteBackground = (background) => {
|
||||
ensureBlockPanelEngaged()
|
||||
const value = String(background || '').trim()
|
||||
|
||||
if (!CALLOUT_BACKGROUND_OPTIONS.includes(value)) {
|
||||
if (!QUOTE_BACKGROUND_OPTIONS.includes(value)) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -2839,6 +2882,8 @@ const handleKeydown = (event) => {
|
||||
@delete-line="onPreviewDeleteLine"
|
||||
@merge-with-previous-line="onPreviewMergeWithPreviousLine"
|
||||
@edit-image="onPreviewEditImage"
|
||||
@line-focus="handleLiveLineFocus"
|
||||
@line-blur="handleLiveLineBlur"
|
||||
@slash-update="onLiveSlashUpdate"
|
||||
@slash-end="onLiveSlashEnd"
|
||||
@slash-apply="onLiveSlashApply"
|
||||
|
||||
Reference in New Issue
Block a user