fix: 에디터 이미지 버튼 = 바로 업로드(팝업 제거) — 댓글창 OK 잘림 해결
CI / build (push) Failing after 12m20s

- Toast UI 기본 이미지 팝업(File/URL/Description/OK)이 작은 댓글창/하단 위치에서 잘려
  OK 를 못 누르던 문제 → 커스텀 툴바 이미지 버튼으로 교체(클릭 시 바로 파일선택→업로드→삽입)
- 서버 업로드(URL) 그대로

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
ByungCheol
2026-06-07 20:16:14 +09:00
parent f7f75b7fb1
commit 2e2c784f4c
+41 -13
View File
@@ -17,6 +17,7 @@ const props = defineProps({
const emit = defineEmits(['update:modelValue'])
const el = ref(null)
const imgInput = ref(null)
let editor = null
// 에디터가 마지막으로 emit 한 값. 부모가 되돌려준 echo 를 구분해 입력 중 setMarkdown 으로 끊기지 않게.
let lastEmitted = props.modelValue || ''
@@ -28,6 +29,34 @@ async function uploadCompressed(fileOrBlob) {
return url
}
// 커스텀 이미지 버튼 클릭 → 파일 선택 → 업로드 → 에디터에 삽입
// (Toast UI 기본 이미지 팝업이 작은 댓글창에서 잘려 OK 를 못 누르는 문제 회피)
async function onImagePick(e) {
const file = e.target.files?.[0]
e.target.value = ''
if (!file || !editor) return
try {
const url = await uploadCompressed(file)
const alt = file.name.replace(/\.[^.]+$/, '')
editor.exec('addImage', { imageUrl: url, altText: alt })
} catch {
/* 업로드 실패 시 미삽입 */
}
}
function makeImageButton() {
const btn = document.createElement('button')
btn.type = 'button'
btn.className = 'toastui-editor-toolbar-icons image'
btn.style.margin = '0'
btn.setAttribute('aria-label', '이미지')
btn.addEventListener('click', (ev) => {
ev.preventDefault()
imgInput.value?.click()
})
return btn
}
onMounted(() => {
editor = new Editor({
el: el.value,
@@ -39,24 +68,20 @@ onMounted(() => {
placeholder: props.placeholder,
usageStatistics: false,
autofocus: false,
// 기본 이미지 버튼(팝업)을 커스텀(바로 업로드)으로 교체
toolbarItems: [
['heading', 'bold', 'italic', 'strike'],
['hr', 'quote'],
['ul', 'ol', 'task', 'indent', 'outdent'],
['table', { name: 'image', tooltip: '이미지', el: makeImageButton() }, 'link'],
['code', 'codeblock'],
],
events: {
change: () => {
lastEmitted = editor.getMarkdown()
emit('update:modelValue', lastEmitted)
},
},
hooks: {
// 이미지 추가 시 base64 대신 서버 업로드 → URL 삽입
addImageBlobHook: async (blob, callback) => {
try {
const url = await uploadCompressed(blob)
callback(url, '')
} catch {
/* 업로드 실패 시 미삽입 */
}
return false
},
},
})
})
@@ -80,5 +105,8 @@ onBeforeUnmount(() => {
</script>
<template>
<div ref="el"></div>
<div>
<div ref="el"></div>
<input ref="imgInput" type="file" accept="image/*" hidden @change="onImagePick" />
</div>
</template>