- Toast UI 기본 이미지 팝업(File/URL/Description/OK)이 작은 댓글창/하단 위치에서 잘려 OK 를 못 누르던 문제 → 커스텀 툴바 이미지 버튼으로 교체(클릭 시 바로 파일선택→업로드→삽입) - 서버 업로드(URL) 그대로 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -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>
|
||||
<div ref="el"></div>
|
||||
<input ref="imgInput" type="file" accept="image/*" hidden @change="onImagePick" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user