글쓰기 입력과 썸네일 표시 보정

This commit is contained in:
2026-05-02 10:18:35 +09:00
parent f3db10f015
commit 77191ef7da
12 changed files with 74 additions and 12 deletions

View File

@@ -20,6 +20,7 @@ const mediaItems = ref([])
const mediaPickerTarget = ref(null)
const isMediaPickerOpen = ref(false)
const isLoadingMedia = ref(false)
const isComposingText = ref(false)
let blockIdSeed = 0
const imageWidthOptions = [
@@ -327,7 +328,11 @@ const setBlockRef = (element, index) => {
if (element) {
blockRefs.value[index] = element
if (isTextBlock(editorBlocks.value[index]) && element.innerText !== editorBlocks.value[index]?.text) {
if (
!isComposingText.value
&& isTextBlock(editorBlocks.value[index])
&& element.innerText !== editorBlocks.value[index]?.text
) {
element.innerText = editorBlocks.value[index]?.text || ''
}
}
@@ -447,12 +452,36 @@ const updateBlockText = (event, index) => {
block.text = text
activeBlockId.value = block.id
if (isComposingText.value || event.isComposing) {
return
}
applyMarkdownShortcut(block, index)
updateSlashQuery(block)
updateSlashMenuDirection(index)
emitContent()
}
/**
* 한글 등 조합형 텍스트 입력 시작 처리
* @returns {void}
*/
const startTextComposition = () => {
isComposingText.value = true
}
/**
* 한글 등 조합형 텍스트 입력 종료 처리
* @param {CompositionEvent} event - 조합 종료 이벤트
* @param {number} index - 블록 인덱스
* @returns {void}
*/
const finishTextComposition = (event, index) => {
isComposingText.value = false
updateBlockText(event, index)
}
/**
* 마크다운 입력 단축 문법 적용
* @param {Object} block - 에디터 블록
@@ -660,13 +689,13 @@ const selectMediaItem = (mediaItem) => {
...block.images,
{
url: mediaItem.url,
alt: mediaItem.title,
alt: '',
width: 'regular'
}
]
} else {
block.url = mediaItem.url
block.alt = mediaItem.title
block.alt = ''
}
emitContent()
@@ -693,7 +722,7 @@ const handleImageUpload = async (event, block) => {
if (file) {
block.url = file.url
block.alt = block.alt || file.name.replace(/\.[^.]+$/g, '')
block.alt = ''
emitContent()
}
} finally {
@@ -723,7 +752,7 @@ const handleGalleryUpload = async (event, block) => {
...block.images,
...uploadedFiles.map((file) => ({
url: file.url,
alt: file.name.replace(/\.[^.]+$/g, ''),
alt: '',
width: 'regular'
}))
]
@@ -954,7 +983,7 @@ defineExpose({
<input
v-if="block.url"
v-model="block.alt"
class="admin-block-editor__caption mt-3 w-full border-0 bg-transparent text-center text-sm text-muted outline-none placeholder:text-soft"
class="admin-block-editor__caption mt-3 hidden w-full border-0 bg-transparent text-center text-sm text-muted outline-none placeholder:text-soft group-hover:block group-focus-within:block"
type="text"
placeholder="이미지 설명"
@input="emitContent"
@@ -1008,6 +1037,8 @@ defineExpose({
:data-show-placeholder="shouldShowPlaceholder(block, index)"
@focus="activateBlock(block)"
@input="updateBlockText($event, index)"
@compositionstart="startTextComposition"
@compositionend="finishTextComposition($event, index)"
@keydown.enter="handleEnter($event, index)"
@keydown.down="highlightNextCommand"
@keydown.up="highlightPreviousCommand"

View File

@@ -10,7 +10,14 @@ defineProps({
<template>
<article class="post-card site-section">
<div class="post-card__body site-section-body flex gap-4">
<div class="post-card__thumb h-20 w-36 shrink-0 rounded-lg bg-[linear-gradient(135deg,#06333a,#f4a261)]" />
<img
v-if="post.featuredImage"
class="post-card__thumb h-20 w-36 shrink-0 rounded-lg bg-surface object-cover"
:src="post.featuredImage"
:alt="post.title"
loading="lazy"
>
<div v-else class="post-card__thumb h-20 w-36 shrink-0 rounded-lg bg-[linear-gradient(135deg,#06333a,#f4a261)]" />
<div class="post-card__content min-w-0">
<h2 class="post-card__title text-base font-semibold leading-tight">
<NuxtLink class="post-card__title-link hover:opacity-70" :to="post.to">